Merkwürdiges Verhalten des Präprozessors



  • Hi,

    das lässt mir jetzt doch keine Ruhe. (ein Unicodeproblem)

    #define POOGEEXCEPTIONMAKEFILEUNICODE( x ) L ## (x
    #define POOGEEXCEPTION( x ) throw Pooge::Exception( x, POOGEEXCEPTIONMAKEFILEUNICODE( __FILE__ ), __LINE__ );
    

    Geht nicht:

    error C2065: 'L__FILE__': nichtdeklarierter Bezeichner
    error C3861: 'L__FILE__': Bezeichner wurde auch mit einer argumentbezogenen Suche nicht gefunden

    Wenn ich in POOGEEXCEPTION(x) aber statt dem POOGEEXCEPTIONMAKEFILEUNICODE()-Makro einfach _T() verwende (das gleich definiert ist wie POOGEEXCEPTIONMAKEFILEUNICODE funktioniert es einwandfrei!).

    Und warum geht das nicht?

    #define POOGEEXCEPTION( x ) throw Pooge::Exception( x, L ## (__FILE__), __LINE__ );
    

    Hier kommt:

    error C3861: 'L': Bezeichner wurde auch mit einer argumentbezogenen Suche nicht gefunden

    Warum wertet er nicht zuerst __FILE__ aus?
    ChrisM



  • C-Standard, 6.10.3.4:

    After all parameters in the replacement list have been substituted and # and ##
    processing has taken place, all placemarker preprocessing tokens are removed. Then, the
    resulting preprocessing token sequence is rescanned, along with all subsequent
    preprocessing tokens of the source file, for more macro names to replace.

    ## wird vor __FILE__ ausgewertet, da hast du keine Chance ohne ein Hilfsmakro. 🙂

    Und warum geht das nicht?

    #define POOGEEXCEPTION( x ) throw Pooge::Exception( x, L ## (__FILE__), __LINE__ );
    

    Nunja, Klammern haben bei Makros keine spezielle Bedeutung. Dieses Makro expandiert also zu:

    POOGEEXCEPTION(0) // wird zu:
    throw Pooge::Exception( 0, L("foo.cpp"), 2 );
    

    So ergibt das L aber wenig Sinn.

    edit:
    Mit einem zweiten Hilfsmakro gehts.

    #define T__(x) L ## x
    #define T(x) T__(x)
    #define foo T(__FILE__)
    
    // wird korrekt ausgewertet:
    foo;
    


  • Hi,

    gut, aber warum geht es dann auch mit dem Hilfsmakro nicht? 😞

    #define L__FILE__ __FILE__

    Nein, das bringt nichts. Dann bleibt am Ende ja einfach __FILE__ dastehen und ich hätte mir den ganzen Aufwand sparen können und gleich __FILE__ hinschreiben können. So kriege ich auch nicht den Filenamen als Unicode. 😞

    Trotzdem vielen Dank!!

    ChrisM



  • Hi,

    ok, hat sich geklärt, man braucht noch ein Hilfsmakro.

    #define POOGEEXCEPTIONMAKEUNICODEINTERNAL( x ) L ## x
    #define POOGEEXCEPTIONMAKEUNICODE( x ) POOGEEXCEPTIONMAKEUNICODEINTERNAL( x )
    #define POOGEEXCEPTION( x ) throw Pooge::Exception( x, POOGEEXCEPTIONMAKEUNICODE( __FILE__ ), __LINE__ );

    Ansonsten wird das Ganze zu T(__FILE__) ausgewertet.

    Danke nochmal an cd9000 für die Hilfe hier und im IRC! 🙂

    ChrisM


Anmelden zum Antworten