9

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?

Community
  • 1
  • 1
MikeT
  • 51,415
  • 16
  • 49
  • 68
  • Your version of the GCC compiler could not support C++14...just a guess, also because I'm not aware of this feature in C++14, or any other version of C++. – nbro Aug 19 '16 at 21:48
  • I'm downloading what could be, a later version of MinGW from [MinGW Distro - nuwen.net](https://nuwen.net/mingw.html). Perhaps this will work. It's not that need this feature rather that I can learn from resolving the issue. – MikeT Aug 19 '16 at 22:00
  • I believe that the compiler was the issue. However, I'm now facing an issue with what I think is my version of windows 7/having a 64 bit processor. i.e. I'm getting `c:/mingw/mingw/bin/../lib/gcc/x86_64-w64-mingw32/6.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: i386 architecture of input file ``obj\Debug\myotherfile.o' is incompatible with i386:x86-64 output collect2.exe: error: ld returned 1 exit status` I think I'll revert to supplied MinGW and not use both types of initialisation as per c++11. Perhaps when I get more familiar with C++. I'll look at resolving that. – MikeT Aug 19 '16 at 22:24
  • 1
    @MikeT You could try downloading a 64-bit MinGW toolchain from [here](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/). I've never had trouble with those. – Praetorian Aug 19 '16 at 22:27
  • Ok the issue, as per the previous comment, appears to have been with the object files. A clean was required. – MikeT Aug 19 '16 at 22:41
  • @Praetorian. As per my previous comment. Problem was with me not the download. I should have read the message rather than seeing the I386 architecture message and then assuming it's 64 bit/Windows 7 issue. However, thanks for the links. Much better layout. – MikeT Aug 19 '16 at 22:44
  • `-std=c++14 -std=c++98 -std=c++0x -std=c++11`. Use only the one you use and remove the others. If I remember, it is the last option which wins, so you don't use C++14 but C++11. – Jarod42 Aug 19 '16 at 23:55
  • @Jarod42 I Was only using **-std=c++14** I think, as build log showed 'g++.exe -Wall -fexceptions -g -std=c++14 -c "D:\C++ Projects\gettingStarted\main.cpp" -o obj\Debug\main.o'. Issue was compiler version as comes with Code::Blocks, downloaded 6.0.1 and that worked. Thanks for the input though. – MikeT Aug 20 '16 at 00:04

1 Answers1

11
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.

Praetorian
  • 106,671
  • 19
  • 240
  • 328