c++switch-statementlanguage-lawyerc++14constexpr

Can initialization of static constant be skipped by 'case' label?


I have a constant declared in one case of my switch statement:

void foo( int& v ) {
    switch( v ) {
    case 0:
        static constexpr int c{ 0 };
        break; 
    case 1:
        v = c;
        break;
    }
}

Everything works fine in GCC, Clang and EDG. But if I compile the program in Visual Studio, it complains

error C2360: initialization of 'c' is skipped by 'case' label

Online demo: https://gcc.godbolt.org/z/jTdnhfzoo

Is it correct that initialization of the constant c can be skipped? Is the program really ill formed or it must be accepted?


Solution

  • Can initialization of static constant be skipped by case label?

    No, not if it's constant initialized as in your function.

    C++14 6.7.4

    Constant initialization ([basic.start.init]) of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered.

    This means that your function is valid and will initialize c when the switch block is first entered. A similarly valid function:

    void foo(int& v) {
        goto bar;
        static constexpr int c{123};
    bar:
        v = c; // assigns 123 to v
    }
    

    Removing constexpr doesn't matter here. It'll still be constant initialization of a block-scope entity with static storage duration and therefore performed when the block is first entered.

    This bug in MSVC is reported here.

    Note: Just because it's valid, it doesn't mean it's a good idea. Don't do this.