Spass mit Compilerunterschieden



  • Moin,

    ist sowas hier legal?

    #include <vector>
    
     int main() { 
         using zahl = int;
         std::vector<unsigned zahl> v = { 1, 2, 3 };
     }
    

    Ich würde ja sagen, nein. Der GCC schluckts, Clang nicht( "type-id cannot have a name" ). Wer hat recht?



  • @Tyrdal sagte in Spass mit Compilerunterschieden:

    Ich würde ja sagen, nein. Der GCC schluckts, Clang nicht( "type-id cannot have a name" ). Wer hat recht?

    Wer laut Standard Recht hat, kann ich nicht sagen, allerdings halte ich diesen aus zwei Wörtern bestehenden Typnamen unsigned int ohnehin für eine Warze und somit ist mir die Antwort von Clang sympathischer 😉 ... nur unsigned tut es auch und daher denkt Clang offenbar, du wolltest diesem Typen hier wie bei einem Funktionsparameter einen Namen geben.


  • Mod

    Ziemlich sicher, dass ein standardkonformer Compiler das nicht schlucken braucht (aber ich bin nicht sicher, ob er es dürfte). "unsigned" hat zwei Bedeutungen im Standard. Zum einen ist es eine Hälfte des Namens von so Typen wie "unsigned long", "unsigned int", usw., zum anderen ist es einer der simple-type-specifier, und zwar mit der Implikation dass "unsigned" in so einem Kontext für den Typen "unsigned int" steht. Das heißt, es kommt immer nur als feststehende Zeichenkette vor für eingebaute Typnamen, und der Typ heißt nun einmal "unsigned int", nicht "unsigned zahl"



  • Mit -pedantic wird der code gewarnt. GNU extensions abzustellen macht kein Unterschied.


  • Mod

    Nein, das ist nicht wohlgeformt. Siehe http://eel.is/c++draft/dcl.type.general#2. (das Typ argument muss ein type-specifier-seq sein).

    Das ist u.a. sowieso eine schlechte Idee weil unsigned eben auch alleinstehend mit einem identifier eine Deklaration bildet, was den Leser in deinem Fall verwirren dürfte.



  • nvc++ und icpc schlucken es.



  • @Columbo sagte in Spass mit Compilerunterschieden:

    Nein, das ist nicht wohlgeformt. Siehe http://eel.is/c++draft/dcl.type.general#2. (das Typ argument muss ein type-specifier-seq sein).

    Das ist u.a. sowieso eine schlechte Idee weil unsigned eben auch alleinstehend mit einem identifier eine Deklaration bildet, was den Leser in deinem Fall verwirren dürfte.

    Damit sollte die Frage beantwortet sein. Das ein paar Compiler das schlucken heißt ja nicht, dass das sinnvoll oder Standard ist.

    Danke


  • Mod

    @SeppJ sagte in Spass mit Compilerunterschieden:

    Ziemlich sicher, dass ein standardkonformer Compiler das nicht schlucken braucht (aber ich bin nicht sicher, ob er es dürfte). "unsigned" hat zwei Bedeutungen im Standard. Zum einen ist es eine Hälfte des Namens von so Typen wie "unsigned long", "unsigned int", usw., zum anderen ist es einer der simple-type-specifier, und zwar mit der Implikation dass "unsigned" in so einem Kontext für den Typen "unsigned int" steht. Das heißt, es kommt immer nur als feststehende Zeichenkette vor für eingebaute Typnamen, und der Typ heißt nun einmal "unsigned int", nicht "unsigned zahl"

    Das ist so nicht korrekt. unsigned ist in jedem Kontext ein simple-type-specifier. unsigned long ist eine type-specifier-seq die aus zwei simple-type-specifiern besteht, und diese Kombination ist explizit erlaubt, und zwar in jeder Reihenfolge und auch getrennt. int const unsigned ist auch ein wohlgeformter Typ. Allerdings schränkt der Standard den Einsatz von unsigned grammatikalisch ein, d.h. die Tatsache, dass ein typedef-name semantisch aequivalent zu int ist, spielt keine Rolle. Es ist in C genauso wenig erlaubt, wie man aus 6.7.2/2 herleiten kann, welches (genau wie im C++ Standard) eine exhaustive Liste aller erlaubter type-specifier Mengen vorgibt.

    Ich habe allerdings eine Vermutung, weshalb dieses Konstrukt von Compilern geschluckt wird: Vor langer Zeit moegen Typ-Aliase noch mittels Makros definiert worden sein, die natuerlich unsigned X erlauben. Als man dann anfing, die Makros durch typedefs zu ersetzen, stellte man fest, dass man an einigen Stellen auf diese Fehlern stieß. Ergo die Ausnahme.

    @john-0 sagte in Spass mit Compilerunterschieden:

    nvc++ und icpc schlucken es.

    NVC++ ist "ISO/ANSI C++17 with GNU compatibility". Wie wir wissen schluckt GCC den Code, das ist also keine Überraschung. (Wird sogar evt. das gleiche front/middle-end einsetzen, aber das konnte ich nicht herausfinden.) Der ICPC Compiler (nicht ICL) basiert immer noch auf EDG, welches ebenfalls GNU Kompatibilität anbietet welche ICPC auch einsetzt.


  • Mod

    So meinte ich das nicht. Im Programm ist es in jedem Kontext ein simple-type-specifier, ja. Ich meinte wo "unsigned" (das Wort!) im Standard vorkommt (außerhalb von viel zu vielen Beispielen). Und da kommt es halt nur vor bei der Grammatikdefinition, wie man Deklarationen aus simple-type-specifiern zusammensetzen kann, und dann noch bei der Definition welche Typen es gibt. Letzteres hat natürlich keine grammatikalische Bedeutung im Programm, sondern wird über die Tabelle in dem Kapitel über simple-type-specifiers zusammengeführt.


  • Mod

    Aha, ich glaube ich habe die Wurzel gefunden. In der EDG internal spec:

    When pcc mode is specified, the front end accepts the traditional C language defined by The C Programming Language, first edition, by Kernighan and Ritchie (K&R), Prentice-Hall, 1978. In addition, it provides almost complete compatibility with the Reiser cpp and Johnson pcc widely used as part of UNIX systems; since there is no documentation of the exact behavior of those programs, complete compatibility cannot be guaranteed.

    In general, when compiling in pcc mode, the front end attempts to interpret a source program that is valid to pcc in the same way that pcc would. However, ANSI features that do not conflict with this behavior are not disabled.

    In some cases where pcc allows a highly questionable construct, the front end will accept it but give a warning, where pcc would be silent (for example: 0x, a degenerate hexadecimal number, is accepted as zero).

    The differences in pcc mode relative to the default ANSI mode are as follows:

    • [..]
    • short, long, and unsigned are treated as “adjectives” in type specifiers, and they may be used to modify a typedef type.

Anmelden zum Antworten