Fehler in 3-zeiligem Programm, Problem bei Bezeichnerwahl



  • Hallo zusammen,

    ich bin gerade dabei mit Bezeichnern zu experimentieren und kann mir nicht erklären wo in folgendem C++-Code der Fehler liegt:

    // x.cpp
    
    struct x;
    
    x f(x x, x y); // ?
    
    int main(){}
    

    Überaschenderweise lässt sich dieser Code kompilieren:

    // x.cpp
    
    struct x;
    
    x f(x y, x x); // ?
    
    int main(){}
    

    Fehlermeldung des g++:
    x.cpp:5:10: Fehler: »x« ist kein Typ

    Hat der zweite Parameter wiederum einen anderen Typ funktioniert alles:

    // x.cpp
    
    struct x;
    
    x f(x x, int y); // ?
    
    int main(){}
    

    Ich habe den Code auch noch mal in C geschrieben. Hier das gleiche Problem. Folgender Code führt zum Fehler:

    // x.c
    
    typedef struct x x;
    
    x f(x x, x y); // ?
    
    int main(){}
    

    Dieser nicht:

    // x.c
    
    typedef struct x x;
    
    x f(x y, x x); // ?
    
    int main(){}
    

    Fehlermeldung des gcc:
    x.c:5:10: Fehler: expected declaration specifiers or »...« before »x«

    Ich habe alles Mögliche ausprobiert. Wenn ich die Funktion mit drei Parametern deklariere funktioniert die Compilierung nur wenn der letzte Parameter den gleichen Bezeichner hat wie der Typ...

    Die Option -Wall ergibt weder bei erfolgreicher noch bein fehlgeschlagener Compilierung weitere Ausgaben. Gleiches gilt für -std=c99 beim gcc.

    Die Versionen der Compiler:
    g++ -v und gcc -v liefern beide:
    gcc-Version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5

    Mir ist natürlich klar, dass man verschiedene Bezeichner für Typen und Variablen wählen sollte. Ich möchte bloß das Prinzip verstehen nach dem ich Bezeichner wählen kann.

    Ich hoffe mir kann jemand sagen was der Fehler ist oder ob der g++/gcc hier einfach vom Standard abweicht (was wirklich tragisch wäre :P).

    MfG Tobi.

    Edit: Titel unmittelbar geändert



  • In dem Moment, wo du "x x" deklarierst, überdeckt die lokale Variable x" den Typ "x".

    Wie wärs mit Aussagekräftigen namen? Oder namenskonventionen, die sowas verhindern?

    struct X;
    foo(X x, X y);
    


  • Noch mehr Ad-Hoc-Lösungen:

    x f(x x, ::x y);
    
    x f(x x, decltype(x) y);
    


  • Ach so ist das.. 🙂

    Ich dachte der Compiler interpretiert beim zweiten Parameter das erste Wort als Typ und das Zweite als Variablenbezeichner. Aber das erklärt natürlich das Problem. In C++ funktioniert auch die Lösung mit dem universellen Namespace.

    Danke!



  • Ich denke folgende Frage hat noch etwas mit dem Thread zu tun, also hänge ich sie mal an.

    Jetzt frage ich mich was es dann für einen Sinn macht Typen und Variablen gleiche Namen geben zu können wenn der Compiler nicht merkt dass an einer Stelle beispielsweise ein Typ benötigt wird und entsprechend einen Typ mit dem angegebenen Bezeichner sucht (so wie ich es mir beim Beispiel oben erst vorgestellt habe).


  • Mod

    Tobi. schrieb:

    Jetzt frage ich mich was es dann für einen Sinn macht Typen und Variablen gleiche Namen geben zu können wenn der Compiler nicht merkt dass an einer Stelle beispielsweise ein Typ benötigt wird und entsprechend einen Typ mit dem angegebenen Bezeichner sucht (so wie ich es mir beim Beispiel oben erst vorgestellt habe).

    Weil's doof ist, wenn jemand irgendwo im Projekt einen neuen Typ einführt, der zufällig so heißt wie eine deiner Variablen und plötzlich funktioniert dein Code nicht mehr.



  • Tobi. schrieb:

    In C++ funktioniert auch die Lösung mit dem universellen Namespace.

    Universeller Namespace...? Das ist der globale Namespace 😉

    Jetzt frage ich mich was es dann für einen Sinn macht Typen und Variablen gleiche Namen geben zu können wenn der Compiler nicht merkt dass an einer Stelle beispielsweise ein Typ benötigt wird und entsprechend einen Typ mit dem angegebenen Bezeichner sucht (so wie ich es mir beim Beispiel oben erst vorgestellt habe).

    N3337 Paragraph 9.1 Klausel 2 schrieb:

    If a class name is declared in a scope
    where a variable, function, or enumerator of the same name is also declared, then when both declarations
    are in scope, the class can be referred to only using an elaborated-type-specifier:...

    Und weil es gerade um elaborate-type-specifiers geht:

    x f(x x, decltype(x) y);
    

    Fail? Wieso nicht einfach ein elaborate-type-specifier?


  • Mod

    Tobi. schrieb:

    Jetzt frage ich mich was es dann für einen Sinn macht Typen und Variablen gleiche Namen geben zu können wenn der Compiler nicht merkt dass an einer Stelle beispielsweise ein Typ benötigt wird und entsprechend einen Typ mit dem angegebenen Bezeichner sucht (so wie ich es mir beim Beispiel oben erst vorgestellt habe).

    Da Typen und Objekte verschiedene Dinge repräsentieren, und der Bezeichner sich auf diese Repräsentationen beziehen sollte, sollte sich diese Frage eigentlich gar nicht stellen.


Anmelden zum Antworten