visual c++: __LINE__ geht nicht als ausdruck für 'case' durch



  • groovemaster schrieb:

    Bitte kreuzen sie an:

    [ ] literal
    [ ] enumerator
    [ ] const variable or static data member of integral or enumeration type initialized with constant expression
    [ ] non-type template parameter of integral or enumeration type
    [ ] sizeof expressio
    

    Ich kann da jedenfalls nichts eindeutig zuordnen. Du etwa?

    das erste (literal) ist damit gemeint.

    btw: es ist definitiv ein bug. guckst du den microsoft-link weiter oben...



  • Ben04 schrieb:

    Ist mir schon klar aber den Sinn decimal davor zu schreiben ergibt sich mir dann nicht.

    Gibt ja auch noch oktal oder hexadezimal und Operator ##.

    net schrieb:

    das erste (literal) ist damit gemeint.

    Sehe gerade, dass du eine C Datei hast (bin von C++ ausgegangen). Dann ist es tatsächlich als Ganzzahlliteral zu werten, da diese dort explizit als constants spezifiziert sind. In C++ sieht das etwas anders aus.

    net schrieb:

    btw: es ist definitiv ein bug. guckst du den microsoft-link weiter oben...

    Dort geht es aber nicht um das konkrete Problem. Lediglich darum, dass durch den Präprozessor __LINE__ falsch evaluiert wird. Damit ist nicht gesagt, dass im Falle von switch/case ebenfalls ein Bug vorliegt. Als Bug kann nur das unterschiedliche Verhalten bei /ZI und /Zi gewertet werden.
    Einigen wir uns also darauf, dass es in C ein Bug ist, in C++ aufgrund der Nachlässigkeit im Standard jedoch keiner (allerdings einer sein sollte). 🙂



  • groovemaster schrieb:

    Ben04 schrieb:

    Ist mir schon klar aber den Sinn decimal davor zu schreiben ergibt sich mir dann nicht.

    Gibt ja auch noch oktal oder hexadezimal und Operator ##.

    Gehen wir davon aus, dass es eine const Variable ist und keine zur Übersetzungszeit bekannte Konstante also wie in folgendem Beispiel die Variable b:

    int a=0;
    const int b = a;
    

    Hier zu fordern, dass b eine decimal Representation hat ist doch Schwachsinn. b ist aber eine Konstante also könnte man __LINE__ auf diese Weise implementiren wie es der VC auch scheinbar macht und aus __LINE__ eine (__LINE__Var+x) macht.

    Sowie ich den Link verstanden hab diehnt das dazu, dass assert und co auch noch die richtige Zeilennumber anzeigt wenn irgendwo während des Debuggen eine Zeile hinzugefügt wird ohne neuübersetzen zu müssen.

    Wenn __LINE__ aber einen zur Übersetzungszeit bekannter Ausdruck wäre dann würde decimal durschaus Sinn machen, um 0x1 und (2-1) zu verbieten.



  • Und worauf willst du hinaus?
    Hinter __LINE__ verbirgt sich nicht einfach nur ein Wert eines Typs, so wie das bei Variablen oder Literalen der Fall ist. Die Repräsentation ist ebenfalls zu beachten, da Makros nunmal nichts anderes als Texte darstellen. Und da macht decimal durchaus Sinn. So wird garantiert, dass zB aus x##__LINE__ nicht irgendwas wie x0x10 wird, sondern x16.



  • groovemaster schrieb:

    Und worauf willst du hinaus?
    Hinter __LINE__ verbirgt sich nicht einfach nur ein Wert eines Typs, so wie das bei Variablen oder Literalen der Fall ist. Die Repräsentation ist ebenfalls zu beachten, da Makros nunmal nichts anderes als Texte darstellen. Und da macht decimal durchaus Sinn. So wird garantiert, dass zB aus x##__LINE__ nicht irgendwas wie x0x10 wird, sondern x16.

    Wenn __LINE__ durch 123 oder ähnlich in jedem Fall ersetz werden würde dann müsste auch "case __LINE__:" funktionieren da nachdem der Präprocessor drüber gelaufen ist es keine Möglichkeit für den Compiler mehr gibt 123 von 123 zu unterscheiden.

    Da es deiner Meinung nach aber legal ist "case __LINE__:" abzulehenen ist es auch legal __LINE__ zu etwas anderem als 123 expandiren zu lassen (da man es sonst gar nicht ablehnen kann). Da es sich um eine Laufzeitkonstante handeln muss (da man es sonst ja nicht abgelehnt werden würde) bleibt eigentlich als einzige Möglichkeit eine compilerinterne Variable.

    Bei einer compilerinterne Variable von decimal ist aber Schwachsinn. Das bedeute also, dass es nicht erlaubt ist eine compilerinterne Variable zu verwenden. Die einzige Alternative ist ein Integerliteral oder die Combination mehrer Literale (1+1) und in beiden Fälle würde "case __LINE__:" kompiliert werden.

    Hast du jetzt verstanden worauf ich hinaus will?

    auch nicht sagen was bei x##__LINE__ rauskommt.

    Die einzige Situation in der der Kompiler



  • Ben04 schrieb:

    Wenn __LINE__ durch 123 oder ähnlich in jedem Fall ersetz werden würde

    Und wer garantiert dir das?

    Ben04 schrieb:

    Da es deiner Meinung nach aber legal ist "case __LINE__:" abzulehenen ist es auch legal __LINE__ zu etwas anderem als 123 expandiren zu lassen

    Korrekt. Es geht dabei aber nicht um den Wert ansich, sondern einzig und allein um die Repräsetation dessen.

    Ben04 schrieb:

    Bei einer compilerinterne Variable von decimal ist aber Schwachsinn.

    Du hast immer noch nicht kapiert, dass Makros nicht zu Werten, sondern zu Texten evaluieren.

    Vielleicht hast du mich ja auch falsch verstanden. Ich sage nicht, dass es falsch ist, wenn case __LINE__ akzeptiert. Ich sage lediglich, dass es aufgrund der Unzulänglichkeiten im Standard kein Bug ist, wenn es nicht so ist. Wie ich weiter oben schon sagte, das einzige was beim MSC als Bug zu werten ist, ist das unterschiedliche Verhalten bei unterschiedlichen Compilereinstellungen.



  • groovemaster schrieb:

    Korrekt. Es geht dabei aber nicht um den Wert ansich, sondern einzig und allein um die Repräsetation dessen.

    Ok kannst du mir irgendeine mögliche Expansion von __LINE__ nennen die
    a) kein Ganzzahlenliteral (oder zur Übersetzungszeit bekannter Ausdruck) ist.
    b) in einer decimalen Representation ist.
    Ich kenne jedenfals nichts das sowohl a) wie auch b) genügt und per Ausschlussverfahren heißt das, dass __LINE__ zu einem decimalen Ganzzahlenliteral expandiren muss.



  • Ben04 schrieb:

    a) kein Ganzzahlenliteral

    Ein Präprozessor könnte bei

    cout << __LINE__ << endl;
    

    zB sowas machen

    cout << (__Internal_line_42 + xx) << endl;
    

    , was vom Compiler dann entsprechend verarbeitet wird. Normalerweise sollten Präprozessor und Compiler voneinander unabhängig arbeitende Einheiten sein, der MSC scheint das aber nicht so eng zu sehen. Ich wüsste auch nichts, was seitens des Standards dagegen sprechen sollte.

    Ben04 schrieb:

    b) in einer decimalen Representation ist.

    s.o.

    Ich denke, es wurde von meiner Seite alles gesagt. Und dabei wollen wir es belassen. Finde dich damit ab, dass der MSC es nicht akzeptiert. Ob du es nun Bug nennst oder nicht, spielt letztendlich keine Rolle. Seitens des Standards ist dies aufgrund gewisser Unzulänglichkeiten nicht zweifelsfrei nachweisbar, imo.



  • groovemaster schrieb:

    cout << __LINE__ << endl;
    

    zB sowas machen

    cout << (__Internal_line_42 + xx) << endl;
    

    , was vom Compiler dann entsprechend verarbeitet wird...

    mag ja sein, aber diese verarbeitung muss so aussehen, dass er (__Internal_line_42 + xx) als zahl nimmt, und zwar so, als hätte jemand eine dezimalzahl hingeschrieben. alles andere geht nicht...



  • groovemaster schrieb:

    cout << (__Internal_line_42 + xx) << endl;
    

    IMO wird b) daruch nicht erfüllt.

    groovemaster schrieb:

    s.o.

    "siehe oben" oder für was soll das stehen?

    Dein x##__LINE__ ist jedenfals undefiniert fals dein Vorschlag b) erfüllen würde.


Anmelden zum Antworten