![]() |
|
|||||||
| Newsgroup de.comp.lang.iso-c++ SO-konformes C++. |
![]() |
|
|
Themen-Optionen | Ansicht |
|
#1
|
|||
|
|||
|
Hallo,
der folgende (minimierte) Code compiliert anstandslos (auch bei -pedantic -ansi -Wall -Wextra) mit g++ 3.4.4 / 4.2.4 auf Solaris sowie g++ 4.3.3 auf Linux. Ein C++ Code-Analysator stolpert jedoch darüber und auch der Comeau-Online-Compiler spuckt an der gleichen Stelle eine Fehlermeldung aus. -----8<----- #include <iostream> template<typename T_TYPE> class TArray { T_TYPE array[2]; }; struct t_outer { struct { struct t_inner { char foo[4]; }; TArray<t_inner> bar; } element; }; int main() { t_outer test; std::cout << sizeof(test) << "\n"; } -----8<----- Comeau: ComeauTest.c(16): error: a template argument may not reference an unnamed type TArray<t_inner> bar; ^ Wer hat hier Recht, GCC oder Comeau? (Ich vermute mal letzterer.) Und wo finde ich dazu was zum genauer Nachlesen im Standard? (Daß sich das Problem leicht mit einem Namen für die mittlere struct korrigieren läßt, weiß ich schon, aber mit einem Verweis auf den Standard hat ein Bug-Report deutlich bessere Chancen.) |
|
|
||||
|
||||
|
|
|
#2
|
|||
|
|||
|
Thomas Dorner wrote:
> Hallo, > > der folgende (minimierte) Code compiliert anstandslos (auch bei > -pedantic -ansi -Wall -Wextra) mit g++ 3.4.4 / 4.2.4 auf Solaris sowie > g++ 4.3.3 auf Linux. Ein C++ Code-Analysator stolpert jedoch darüber > und auch der Comeau-Online-Compiler spuckt an der gleichen Stelle eine > Fehlermeldung aus. > > -----8<----- > #include <iostream> > > template<typename T_TYPE> > class TArray { > T_TYPE array[2]; > }; > > struct t_outer { > struct { > struct t_inner { > char foo[4]; > }; > TArray<t_inner> bar; > } element; > }; > > int main() { > t_outer test; > std::cout << sizeof(test) << "\n"; > } > -----8<----- > > Comeau: > ComeauTest.c(16): error: a template argument may not reference an unnamed > type > TArray<t_inner> bar; > ^ > > Wer hat hier Recht, GCC oder Comeau? > (Ich vermute mal letzterer.) Du vermutest richtig. > Und wo finde ich dazu was zum genauer Nachlesen im Standard? 14.3.1/2: A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter. |
|
#3
|
|||
|
|||
|
Rolf Magnus wrote:
> Thomas Dorner wrote: > >> Hallo, >> >> der folgende (minimierte) Code compiliert anstandslos (auch bei >> -pedantic -ansi -Wall -Wextra) mit g++ 3.4.4 / 4.2.4 auf Solaris sowie >> g++ 4.3.3 auf Linux. Ein C++ Code-Analysator stolpert jedoch darüber >> und auch der Comeau-Online-Compiler spuckt an der gleichen Stelle eine >> Fehlermeldung aus. >> >> -----8<----- >> #include <iostream> >> >> template<typename T_TYPE> >> class TArray { >> T_TYPE array[2]; >> }; >> >> struct t_outer { >> struct { >> struct t_inner { >> char foo[4]; >> }; >> TArray<t_inner> bar; >> } element; >> }; >> >> int main() { >> t_outer test; >> std::cout << sizeof(test) << "\n"; >> } >> -----8<----- >> >> Comeau: >> ComeauTest.c(16): error: a template argument may not reference an unnamed >> type >> TArray<t_inner> bar; >> ^ >> >> Wer hat hier Recht, GCC oder Comeau? >> (Ich vermute mal letzterer.) > > Du vermutest richtig. > >> Und wo finde ich dazu was zum genauer Nachlesen im Standard? > > 14.3.1/2: > > A local type, a type with no linkage, an unnamed type or a type compounded > from any of these types shall not be used as a template-argument for a > template type-parameter. Und ich denke der paragraph der t_inner internal linkage gibt ist folgender: 3.5/5: In addition, a member function, static data member, class or enumeration of class scope has external linkage if the name of the class has external linkage. ("class" wurde korrigiert zu "named class" im c++0x draft) In diesem fall hat die klasse garkeinen namen, also hat der member auch keine external linkage (und auch keine internal, weil er nicht in der vorherigen liste auftaucht). Allerdings glaube ich der vorherige paragraph der den sachen external linkage gibt sollte sagen: - a named class that is not a member of another class (clause 9), or an unnamed class that is not a member of another class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3); Momentan denke ich dass wenn es einfach sagt "a named class", es tatsächlich t_inner external linkage gibt. Oder aber man ändert 3.5/5 sodass es sagt "if and only if" anstatt einfach nur "if". Was denkt ihr? Man könnte natürlich vermuten dass comeau die klasse als template argument ablehnt weil es mit einem type ohne linkage "compounded" ist, aber selber external linkage hat. Ich denke aber nicht dass das der fall ist, denn wenn t_inner wirklich external linkage hat, denke ich wird es für den compiler unmöglich einen eindeutigen namen zu manglen der dann auch diese klasse gegeneinander in mehreren TUs linkt. Also denke ich t_inner hat tatsächlich keine linkage. |
|
#4
|
|||
|
|||
|
Johannes Schaub (litb) wrote:
>>> struct t_outer { >>> struct { >>> struct t_inner { >>> char foo[4]; >>> }; >>> TArray<t_inner> bar; >>> } element; >>> }; >>> >>> int main() { >>> t_outer test; >>> std::cout << sizeof(test) << "\n"; >>> } >>> -----8<----- >>> >>> Comeau: >>> ComeauTest.c(16): error: a template argument may not reference an >>> unnamed type >>> TArray<t_inner> bar; >>> ^ >>> >>> Wer hat hier Recht, GCC oder Comeau? >>> (Ich vermute mal letzterer.) >> >> Du vermutest richtig. >> >>> Und wo finde ich dazu was zum genauer Nachlesen im Standard? >> >> 14.3.1/2: >> >> A local type, a type with no linkage, an unnamed type or a type >> compounded from any of these types shall not be used as a >> template-argument for a template type-parameter. > > Und ich denke der paragraph der t_inner internal linkage gibt ist > folgender: 3.5/5: > > In addition, a member function, static data member, class or enumeration > of class scope has external linkage if the name of the class has external > linkage. > > ("class" wurde korrigiert zu "named class" im c++0x draft) In diesem fall > hat die klasse garkeinen namen, also hat der member auch keine external > linkage (und auch keine internal, weil er nicht in der vorherigen liste > auftaucht). In dem von mir zitierten Paragraphen wurden "unnamed types" ja eh schon ausgeschlossen, also braucht man sich eigentlich gar nicht mehr um die Linkage zu kümmern. > Man könnte natürlich vermuten dass comeau die klasse als template argument > ablehnt weil es mit einem type ohne linkage "compounded" ist, aber selber > external linkage hat. Meine Vermutung wäre - basierend auf der Fehlermeldung - eher gewesen, daß er sich darüber beschwert, daß es mit einem Typ ohne Namen compounded ist. |
|
#5
|
|||
|
|||
|
Rolf Magnus wrote:
> Johannes Schaub (litb) wrote: > >>>> struct t_outer { >>>> struct { >>>> struct t_inner { >>>> char foo[4]; >>>> }; >>>> TArray<t_inner> bar; >>>> } element; >>>> }; >>>> >>>> int main() { >>>> t_outer test; >>>> std::cout << sizeof(test) << "\n"; >>>> } >>>> -----8<----- >>>> >>>> Comeau: >>>> ComeauTest.c(16): error: a template argument may not reference an >>>> unnamed type >>>> TArray<t_inner> bar; >>>> ^ >>>> >>>> Wer hat hier Recht, GCC oder Comeau? >>>> (Ich vermute mal letzterer.) >>> >>> Du vermutest richtig. >>> >>>> Und wo finde ich dazu was zum genauer Nachlesen im Standard? >>> >>> 14.3.1/2: >>> >>> A local type, a type with no linkage, an unnamed type or a type >>> compounded from any of these types shall not be used as a >>> template-argument for a template type-parameter. >> >> Und ich denke der paragraph der t_inner internal linkage gibt ist >> folgender: 3.5/5: >> >> In addition, a member function, static data member, class or enumeration >> of class scope has external linkage if the name of the class has external >> linkage. >> >> ("class" wurde korrigiert zu "named class" im c++0x draft) In diesem fall >> hat die klasse garkeinen namen, also hat der member auch keine external >> linkage (und auch keine internal, weil er nicht in der vorherigen liste >> auftaucht). > > In dem von mir zitierten Paragraphen wurden "unnamed types" ja eh schon > ausgeschlossen, also braucht man sich eigentlich gar nicht mehr um die > Linkage zu kümmern. > Eine "unnamed" klasse bezeichnet eine klasse ohne einen identifier in ihrem kopf: http://www.open-std.org/jtc1/sc22/wg...fects.html#406 . In unserem fall haben wir eine named klasse - der name ist "t_inner". Natürlich ist der code so oder so ill-formed da t_inner ja compounded ist aus einem unnamed type, insofern hast du natürlich recht denke ich. Aber ich wollte eher auf den ungenauen text zur linkage von t_inner aufmerksam machen, weil mir das aufgefallen ist beim "nachforschen" ![]() |
|
#6
|
|||
|
|||
|
Johannes Schaub (litb) wrote:
> Rolf Magnus wrote: > >> Johannes Schaub (litb) wrote: >> >>>>> struct t_outer { >>>>> struct { >>>>> struct t_inner { >>>>> char foo[4]; >>>>> }; >>>>> TArray<t_inner> bar; >>>>> } element; >>>>> }; >>>>> >>>>> int main() { >>>>> t_outer test; >>>>> std::cout << sizeof(test) << "\n"; >>>>> } >>>>> -----8<----- >>>>> >>>>> Comeau: >>>>> ComeauTest.c(16): error: a template argument may not reference an >>>>> unnamed type >>>>> TArray<t_inner> bar; >>>>> ^ >>>>> >>>>> Wer hat hier Recht, GCC oder Comeau? >>>>> (Ich vermute mal letzterer.) >>>> >>>> Du vermutest richtig. >>>> >>>>> Und wo finde ich dazu was zum genauer Nachlesen im Standard? >>>> >>>> 14.3.1/2: >>>> >>>> A local type, a type with no linkage, an unnamed type or a type >>>> compounded from any of these types shall not be used as a >>>> template-argument for a template type-parameter. >>> >>> Und ich denke der paragraph der t_inner internal linkage gibt ist >>> folgender: 3.5/5: >>> >>> In addition, a member function, static data member, class or enumeration >>> of class scope has external linkage if the name of the class has >>> external linkage. >>> >>> ("class" wurde korrigiert zu "named class" im c++0x draft) In diesem >>> fall hat die klasse garkeinen namen, also hat der member auch keine >>> external linkage (und auch keine internal, weil er nicht in der >>> vorherigen liste auftaucht). >> >> In dem von mir zitierten Paragraphen wurden "unnamed types" ja eh schon >> ausgeschlossen, also braucht man sich eigentlich gar nicht mehr um die >> Linkage zu kümmern. >> > > Natürlich ist der code so oder so ill-formed da t_inner ja compounded ist > aus einem unnamed type. Sorry ich glaub ich liege da falsch. Das würde ja nur zutreffen wenn der typ ohne linkage ein sub-typ währe, wie etwa "struct X { struct { } F; };", "void(*)(WithoutLinkage)"; etc. Aber es gibt einen defect report zu ersterem ( defect#62 ), und ein anderer ersetzt den kompletten paragraph (und offenbar wurde er in c++0x entfernt ^^), da ja z.B "void*" auch ein "unnamed type" ist ![]() Insofern würd ich schon sagen dass der aktuelle fall auf "linkage" basiert (und ich denke ich werde hier einen defekt report melden um die linkage klarer zu definieren), der code aber nicht ill-formed aufgrund dem "compounded" satz ist, weil er ja eher genau das gegenteil macht, nämlich als teil eines anderen types fungiert ![]() |
|
|
|
|