Bug-report on templates, static const members and hided non const initialization or in other words, "Writing a really strange code to make g++ crash HOW-TO" ******************************************************************************* ******* My code makes the following versions of g++ crash with Segmentation Fault, no other messages than the segmentation fault itself and how to report a bug occur. 1) g++ (GCC) 3.3.2 20031022 (Red Hat Linux 3.3.2-1) on Feodora Core 1 running inside Cooperative Linux(linux kernel running on top of windows), compiler installed using apt-get getting everything from freshrpms.com 2) g++ (GCC) 3.3.3 (cygwin special), downloaded from cygwin site using the standard installer running in WinXP Professional SP1. 3) g++ (GCC) 3.2.3 (mingw special 20030504-1), downloaded in binary installer from myngw site, it´s running in WinXP Professional SP1. 4) g++ version 3.0.4 running on SunOS 5.8 The system where all versions out of SunOs are running: Toshiba Satellite laptock with an intel Pentium 2.20 Ghz 240 RAM (the other 16 are for the video card???). Does it matter anyway? The comand line its a little dissapointig for a Segmentation Fault: $ g++ main2.cpp The contents of the file main2.cpp are no less dissapointing: (it doesnt do any include, so i post the cpp file itself instead of the ii file which looks exactly the same). ------------------------------------------------------------------------------ --- /STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCOD E/ ------------------------------------------------------------------------------- - int function1() { return 1; } template <class aType> class Class1 { public: static const int var1 = function1(); }; /* Notice that the following line should not be used for static const variables * i agree with that, however it should not make gcc crash but rather show an error * message. At least thats my opinion ;-) */ const int Class1<int>::var1; int main(int argc, char *argv[]) { int var2 = Class1<int>::var1; return 0; } ------------------------------------------------------------------------------ -- /ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCOD E/ ------------------------------------------------------------------------------- - What do i think about the error? (and other error which i think is related): Listening to my opinion is very important, because i am important, i am the center of my universe :-) This is the smallest programm that causes this same error (Segmentation Fault in g++). Trying to reduce it: 1) If I delete the const keyword from the declaration and move function2() to the definition of the variable i get a successfull compilation.vthe program 2) If i delete the line which says "const int Class1<int>::var1;" i get a linker error but no segmentation fault. 3) If i deñete the function2() call and add the number 1 directly and erase the line which says "const int Class1<int>::var1;" i get another successfull compilation. 4) **IMPORTANT** if i make class1 a non template class ( i delete "template <class aType>" and the other template stuff) i get compilation mistakes!!!! this means that building a class as a template make the compiler ignore some errors which is making g++ confused. 5) If i do not instanciate the template i get another succesfull compilation. How to get to the error? First look at a full-working first version of the programm: ------------------------------------------------------------------------------ --- /STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCOD E/ ------------------------------------------------------------------------------- - class Class1 { public: static const int var1 = 1; }; int main(int argc, char *argv[]) { int var2 = Class1::var1; return 0; } ------------------------------------------------------------------------------ -- /ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCOD E/ ------------------------------------------------------------------------------- - This works nice, now, we would like to use func2 to initialize var1... this is the code: ------------------------------------------------------------------------------ --- /STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCOD E/ ------------------------------------------------------------------------------- - int function1() { return 1; } class Class1 { public: static const int var1 = function1(); }; int main(int argc, char *argv[]) { int var2 = Class1::var1; return 0; } ------------------------------------------------------------------------------ -- /ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCOD E/ ------------------------------------------------------------------------------- - This time time compilation fails with the following error: main2.cpp:9: error: field initializer is not constant You might be right, this is not a correct programm, anyway, the compiler still has no errors. Now, imagine i still haven't compile this file so i don't know there is an error in my code , i would like to make everything more general so i will make Class1 a tempate class. New code: ------------------------------------------------------------------------------ --- /STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCODE/STARTCOD E/ ------------------------------------------------------------------------------- - int function1() { return 1; } template <class aType> class Class1 { public: static const int var1 = function1(); }; int main(int argc, char *argv[]) { int var2 = Class1<int>::var1; return 0; } ------------------------------------------------------------------------------ -- /ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCODE/ENDCOD E/ ------------------------------------------------------------------------------- - now gcc bypasess completly the mistake in var1 initialization... it compiles the file (I have no idea what it writes in assembler) and it only reports a mistake in linking time. /full/Path/Hided/For/Reporting/the/Bug/ccnctzKQ.o(.text+0x29):main2.cpp: undefined reference to `Class1<int>::var1' This is already the mistake..... a static const should have no memory so there should be no reference to it, but somehow the combination of template and non static incorrect initilization confuses gcc. Since this is a normal ld mistake i only have to define Class1<int>::var1 to bypass it so i add the line: "const int Class1<int>::var1;" and then get the nasty Segmentation Fault in every plataform that i tried it on. So this is the end of my bug report, i worked a lot to make it very complete and to make this minimal programm to reproduce the bug. I hope you like the report ;-) I guess you wont. Anyway, can you answer me a little additional question: why var1 cannot be initialized by a function, should i use some other mechanism which replaces it? how can i calculate a value for var1 at compile time??? Thank you very much in advance for fixing this, answering my question and continuing to do this great compiler collection which is such an important part of GNU/Linux, hey you see, i haver been reading all this stuff about the role of GNU. Sincerilly, Marcelo Taube
Fixed in 3.4.0 most likely by the parser. Note the code is invalid (without the template): gcc pr17194.cc pr17194.cc:10: error: `int function1()' cannot appear in a constant-expression pr17194.cc:10: error: a function call cannot appear in a constant-expression With the template part: pr17194.cc:10: error: `int function1()' cannot appear in a constant-expression pr17194.cc:10: error: a function call cannot appear in a constant-expression pr17194.cc:19: error: too few template-parameter-lists
It wasn't a regression, so need to fix on any release branch. As for the bug report: thanks a lot, we very much appreciate small testcases with explanation! W.