Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I am using c++14 or is my code, using structs, invalid?

I am revisiting C++ and have been following a tutorial with no real issues. However, I have got to a section on structs which says that in c++14 you can use both non-static initialisation and unifrom initialisation. As per:-

However, in C++14, this restriction was lifted and both can be used. If both are provided, the initializer list/uniform initialization syntax takes precedence. In the above example, Triangle x would be initialized with length and width 2.0.

The code I have is :-

struct Triangle
{
    double length = 1.23; // non-static member initialization
    double width = 2.45;
};

int Triangular()
{
Triangle x{ 2.0, 2.0 }; // uniform initialization

return 0;
}

...... 
int main() ......

However, I cannot get this to compile (I'm using Code::Blocks on Windows 7). If I remove the non-static initialisation and use (i.e remove the = 1.23 and = 2.45 ) then it does compile:-

struct Triangle
{
    double length; // non-static member initialization
    double width;
};

int Triangular()
{
Triangle x{ 2.0, 2.0 }; // uniform initialization

return 0;
}

...... 
int main() ......

My first thought was that I don't have c++14. So I have followed Enabling -std=c++14 flag in Code::Blocks and I appear to have the compiler set to c++14 (one exception is that there was no make.exe so the make program is mingw32-make.exe (as per Settings/Compiler/Toolchain executables).


I have:- GNU GCC compiler

Compiler settings as :-

-std=c++14 compiler flags

-std=c++98 -std=c++0x -std=c++11 as the supercedes

Toolchain Executables as :-

gcc.exe C Compiler g++.exe C++ Compiler g++.exe Linker for dynamic libs ar.exe Linker for static libs GDB/CDB debugger : Default windres.exe Resource compiler mingw32-make.exe Make program

The Project Build options are all blank (So I assume the Code::Block settings are used.)


When I compile the failing code (the first code with the non-static initialisations) I get the following :-

Build Log

g++.exe -Wall -fexceptions -g -std=c++14  -c "D:\C++ Projects\gettingStarted\main.cpp" -o obj\Debug\main.o
D:\C++ Projects\gettingStarted\main.cpp: In function 'int Triangular()':
D:\C++ Projects\gettingStarted\main.cpp:24:22: error: no matching function for call to 'Triangle::Triangle(<brace-enclosed initializer list>)'
 Triangle x{ 2.0, 2.0 }; // uniform initialization
                      ^
D:\C++ Projects\gettingStarted\main.cpp:24:22: note: candidates are:
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: constexpr Triangle::Triangle()
 struct Triangle
        ^
D:\C++ Projects\gettingStarted\main.cpp:16:8: note:   candidate expects 0 arguments, 2 provided
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: constexpr Triangle::Triangle(const Triangle&)
D:\C++ Projects\gettingStarted\main.cpp:16:8: note:   candidate expects 1 argument, 2 provided
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: constexpr Triangle::Triangle(Triangle&&)
D:\C++ Projects\gettingStarted\main.cpp:16:8: note:   candidate expects 1 argument, 2 provided
Process terminated with status 1 (0 minute(s), 0 second(s))
1 error(s), 0 warning(s) (0 minute(s), 0 second(s))

Using the second code (non-static initialisation removed) I just get a warning about x not being used (that's fine I can manage that) as per :-

Build Log

-------------- Build: Debug in gettingStarted (compiler: GNU GCC Compiler)---------------

g++.exe -Wall -fexceptions -g -std=c++14  -c "D:\C++ Projects\gettingStarted\main.cpp" -o obj\Debug\main.o
D:\C++ Projects\gettingStarted\main.cpp: In function 'int Triangular()':
D:\C++ Projects\gettingStarted\main.cpp:24:10: warning: unused variable 'x' [-Wunused-variable]
 Triangle x{ 2.0, 2.0 }; // uniform initialization
          ^
g++.exe  -o bin\Debug\gettingStarted.exe obj\Debug\main.o obj\Debug\myotherfile.o   
Output file is bin\Debug\gettingStarted.exe with size 1.07 MB
Process terminated with status 0 (0 minute(s), 1 second(s))
0 error(s), 1 warning(s) (0 minute(s), 1 second(s))

So I believe that I'm either using invalid code or that I am not compiling using c++14 but rather c++11. Is the issue one of these, or perhaps something else?

like image 441
MikeT Avatar asked Aug 19 '16 21:08

MikeT


1 Answers

Triangle x{ 2.0, 2.0 };

The line above is attempting to perform aggregate initialization of Triangle. However, in C++11, the presence of non-static data member initializers, or default member initializers as they're now known as, prevented Triangle from being an aggregate, and the initialization would fail.

This rule was modified in C++14, and aggregates are now allowed to have default member initializers. It seems your compiler doesn't yet support that. Your example does compile on a conforming C++14 compiler.

like image 63
Praetorian Avatar answered Nov 01 '22 08:11

Praetorian