[Bug c++/45374] New: template keyword incorrectness// failure to parse valid code.
gcc incorrectly handles the following code. The underlying problem is that gcc does not require the "template" keyword in certain places where it should require it. The side effect is that gcc refuses to parse valid code that looks like a template parameter list but really is not. The first templated function call in the main() should be rejected by gcc because the template keyword should be required. The second templated function call is rejected but should be accepted because it's parseable as a combination of "<" and ">" operators and makes sense in that way (Visual Studio accepts this code, again incorrectly; presumably it does not construct a single parse tree). merlin:~: gcc tmp.cc tmp.cc: In function 'int MyTemplatedFunction() [with A = char, int B = 6]': tmp.cc:29: instantiated from here tmp.cc:23: error: 'MyClass<6>' is not a base of 'MyDerivedClass' -- #include template class MyClass { public: int MyFunc() {return B;} }; template class MyDerivedClass: public MyClass { public: int MyFunc() {return 1;} }; template class MyDerivedClass { public: int MyClass; MyDerivedClass(): MyClass(10) {} }; int MyFunc() { return 5; } template int MyTemplatedFunction() { MyDerivedClass *ptr = new MyDerivedClass; return ptr->MyClass::MyFunc(); // should be ptr->template MyClass::MyFunc() // to be parsed as template, but gcc does not require this. } int main() { std::cout << "First time: " <() << std::endl; std::cout << "Next time: " << MyTemplatedFunction() << std::endl; while(1); return 0; } -- Summary: template keyword incorrectness// failure to parse valid code. Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dpovey at gmail dot com GCC build triplet: i686-linux-gnu GCC host triplet: i686-linux-gnu GCC target triplet: i686-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45374
[Bug c++/45374] template keyword incorrectness// failure to parse valid code.
--- Comment #2 from dpovey at gmail dot com 2010-08-23 21:51 --- (In reply to comment #1) Yes you are right, but it is more than that bug, because I created an example where gcc wrongly *rejects* code that it should accept, as well as one where it wrongly accepts code that it should reject. BTW, Visual Studio (2010) has different behavior -- it accepts both of the statements in main(), even though they require different parse trees. However, unlike gcc, it will not *accept* the "template" keyword on the line where (for the first parse tree) it should be required. Thus, fixing this gcc bug will lead people to code in such a way that their code cannot compile in Visual Studio. Dan > Looks related to PR 11814. > -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45374
[Bug c++/44548] New: Link error when defining templated static const variable
Complete code is below [just a few lines]. Note-- bug goes away when I initialize the variable outside the class, not inside. qpo...@merlin: ~$ cat temp.cc template class MyTraits { public: static const T kValue = 0; }; template<> const int MyTraits::kValue; // define it. int main(){ const void * a = &(MyTraits::kValue); } qpo...@merlin: ~$ g++ temp.cc /tmp/ccuYrD0D.o: In function `main': temp.cc:(.text+0x14): undefined reference to `MyTraits::kValue' collect2: ld returned 1 exit status qpo...@merlin: ~$ g++ -v Using built-in specs. Target: i686-linux Configured with: ../configure --build=i686-linux --with-arch=nocona --with-tune=core2 --with-thread=posix --with-as=/usr/local/bin/as --with-ld=/usr/local/bin/ld --with-system-zlib --program-suffix=-4.3 Thread model: posix gcc version 4.3.5 (GCC) qpo...@merlin: ~$ uname -a Linux merlin.fit.vutbr.cz 2.6.32.12 #1 SMP Tue Apr 27 15:10:42 CEST 2010 x86_64 x86_64 x86_64 GNU/Linux qpo...@merlin: ~$ -- Summary: Link error when defining templated static const variable Product: gcc Version: 4.3.5 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dpovey at gmail dot com GCC build triplet: i686-linux-gnu GCC host triplet: i686-linux-gnu GCC target triplet: i686-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44548
[Bug c++/44548] Link error when defining templated static const variable
--- Comment #2 from dpovey at gmail dot com 2010-06-15 22:19 --- I don't agree with you that this is not a bug, although I do agree that I could have coded it differently. Look at http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/explicit_specialization.htm the section on "Explicit specialization of members of class templates". You are right, my syntax was an explicit specialization, and that was pointless and I could have done it a different way, but I believe what I wrote still counts as a definition of the variable-- what else could the syntax possibly mean? I.e. the line: template<> const int MyTraits::kValue; You say this is an explicit specialization; fine, but it is an explicit specialization of the *definition* of the variable. You can't *declare* a class member outside of the class itself, and I'm not specializing the class itself. So either that line needs to be rejected by the compiler, or it needs to work as I intended-- what other possible meaning could it have than the one I intended? The C++ standard doesn't seem to mention whether or not you are allowed to explicitly specialize static const variables that have been defined inside the class, and it does seem a bit pointless to do so, but I think it should either compile or issue an error or warning. -- dpovey at gmail dot com changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44548
[Bug c++/44552] New: specialization of static const class member declaration should issue warning.
If you compile the following code: template class MyTraits { public: static const T kValue = 0; }; template<> const int MyTraits::kValue; // define it. int main(){ const void * a = &(MyTraits::kValue); } g++ will issue no warnings but give linking errors. The statement template<> const int MyTraits::kValue; is in error: it is intended to be a definition of the variable but C++ does not allow specializations of definitions (thanks to pinksia for pointing this out). I really should have templated the definition. However, the statement I did enter can have no possible purpose and I believe a warning should be issued. It is possible that the statement could be meaningful for a non-const static member (I don't know C++ well enough to judge) but it is definitely not meaningful for a static member: thus I believe a warning is in order. -- Summary: specialization of static const class member declaration should issue warning. Product: gcc Version: 4.3.5 Status: UNCONFIRMED Severity: trivial Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dpovey at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44552
[Bug c++/44552] specialization of static const class member declaration should issue warning.
--- Comment #1 from dpovey at gmail dot com 2010-06-15 22:47 --- Sorry, I made a mistake in the last line: I meant "Definitely not meaningful for a const member." -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44552
[Bug c++/44552] specialization of static const class member declaration should issue warning.
--- Comment #5 from dpovey at gmail dot com 2010-06-15 23:22 --- OK thanks guys. -- dpovey at gmail dot com changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||INVALID http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44552
[Bug c++/44548] Link error when defining templated static const variable
--- Comment #7 from dpovey at gmail dot com 2010-06-16 17:57 --- The key thing here is that the value was initialized inside the class. So there is no way to syntactically disambiguate a definition and a declaration of the value outside the class (because normally C++ uses the initialization to tell that you are defining it, but if you initialized it inside the class then it doesn't let you initialize it again outside the class). For non-specialized "declarations/definitions", if they're initialized inside the class C++ is forced to treat the (declaration/definition) without initializer as a definition (I guess because it's more important to be able to define it to declare it). I assumed that when you specialize it, C++ also treats this syntax as a definition. It's possible that I was wrong. If so I think it's a misfeature in the C++ standard. But I really don't know how it's interpreting it. Suppose you do: template class C{ int i = 1; }; template<> int C::i; Let's suppose it treats this as a declaration. What is it declaring? There is no syntax available to *define* the value (because it looks the same as a declaration). Conceivably you could later override the class itself, e.g.: template <> class C { int i = 0; }; But I don't know whether C++ would treat the declaration statement above as somehow relating to this. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44548