The secret of definitions in case



  • Hi,

    ich dachte immer, Definition wären in case-Bereich verboten, da man ansonsten paar Probleme micht Sichtbarkeiten und Gültigkeitsbereichen bekommen könnte. Folgedessen muss man solche in Anweisungsblöcke packen.

    Doch heute wurde ich vom Gegenteil überzeugt:

    // Kompiliert
    switch(var)
    {
        case 1: int a; break;
        case 2: a = 123;
    }
    
    // Kompiliert nat. nicht
    switch(var)
    {
        case 1: { int a; } break;
        case 2: a = 123;
    }
    
    // Kompiliert nicht
    switch(var)
    {
        case 1: string a; break;
        case 2: a = "Hallo";
    }
    
    // Kompiliert
    class A { };
    
    switch(var)
    {
        case 1: A a; break;
        case 2: a = A();
    }
    
    // Huch, kompiliert nicht
    class A { public: A() {} };
    
    switch(var)
    {
        case 1: A a; break;
        case 2: a = A();
    }
    

    ???



  • lustig



  • Mit welchem Compiler denn?



  • Badestrand schrieb:

    Mit welchem Compiler denn?

    Comeau und g++.



  • Mit dem MSVC++05 geht's auch, merkwürdig. Gut, immerhin nur PODs aber sowas ist man ja nicht gewohnt vom Standard (oder welchen Sinn hat das, der sich mir nicht erschließt?) 😕



  • Wirklich interessant, ich habe aber gerade mal den Standard gewälzt und da sieht man auch die Erklärung. Die beiden interessanten Stellen sind

    Standard, 6.7.3 schrieb:

    It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps (77) from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is illformed unless the variable has POD type (3.9) and is declared without an initializer (8.5).

    (77) The transfer from the condition of a switch statement to a case label is considered a jump in this respect

    und (aber nicht mehr ganz so interessant):

    Standard, C.1.4 schrieb:

    C.1.4 Clause 6: statements [diff.stat]
    6.4.2, 6.6.4 (switch and goto statements)
    1 Change: It is now invalid to jump past a declaration with explicit or implicit initializer (except across entire block not entered) Rationale: Constructors used in initializers may allocate resources which need to be deallocated upon leaving the block. Allowing jump past initializers would require complicated runtime determination of allocation. Furthermore, any use of the uninitialized object could be a disaster. With this simple compiletime rule, C++ assures that if an initialized variable is in scope, then it has assuredly been initialized. Effect on original feature: Deletion of semantically welldefined feature.
    Difficulty of converting: Semantic transformation.
    How widely used: Seldom.

    Felix



  • Danke für die Std-Stelle.
    Stranges Verhalten, aber hat bestimmt auch seinen Grund.



  • was mit switch alles geht ist schon irgendwie "krank". man denke nur an duffs device.


Anmelden zum Antworten