struct S { int a, b; }; constexpr int foo (int x) { switch (x) { int i; case 1: int j; case 2: i = 1; j = 2; return i + j; case 3: S s; return 2; case 4: s.a = 3; s.b = 4; [[fallthrough]]; default: return s.a + s.b; } } static_assert (foo (1) == 3); static_assert (foo (2) == 3); static_assert (foo (3) == 2); static_assert (foo (4) == 7); static_assert (foo (42) == 7); IMHO this is valid for C++20 and above, in C++17 variables with vacuous initialization aren't valid in constant expressions, in C++20 I think they should be valid if one doesn't actually use the uninitialized values. Still, g++ rejects it with <source>:29:24: error: non-constant condition for static assertion 29 | static_assert (foo (1) == 3); | ~~~~~~~~^~~~ in 'constexpr' expansion of 'foo(1)' <source>:29:20: 29 | static_assert (foo (1) == 3); | ~~~~^~~ <source>:12:9: error: modification of 'i' from outside current evaluation is not a constant expression 12 | i = 1; | ~~^~~ <source>:30:24: error: non-constant condition for static assertion 30 | static_assert (foo (2) == 3); | ~~~~~~~~^~~~ in 'constexpr' expansion of 'foo(2)' <source>:30:20: 30 | static_assert (foo (2) == 3); | ~~~~^~~ <source>:12:9: error: modification of 'i' from outside current evaluation is not a constant expression 12 | i = 1; | ~~^~~ <source>:32:24: error: non-constant condition for static assertion 32 | static_assert (foo (4) == 11); | ~~~~~~~~^~~~~ in 'constexpr' expansion of 'foo(4)' <source>:32:20: 32 | static_assert (foo (4) == 11); | ~~~~^~~ <source>:19:11: error: modification of 's' from outside current evaluation is not a constant expression 19 | s.a = 3; | ~~~~^~~ <source>:33:25: error: non-constant condition for static assertion 33 | static_assert (foo (42) == 11); | ~~~~~~~~~^~~~~ in 'constexpr' expansion of 'foo(42)' <source>:33:20: 33 | static_assert (foo (42) == 11); | ~~~~^~~~ <source>:23:11: error: modification of 's' from outside current evaluation is not a constant expression 23 | s.a = 5; | ~~~~^~~ and clang++ with even weirder <source>:32:16: error: static assertion expression is not an integral constant expression 32 | static_assert (foo (4) == 11); | ^~~~~~~~~~~~~ <source>:19:7: note: unimplemented constexpr lambda feature: captures not currently allowed (coming soon!) 19 | s.a = 3; | ^ <source>:32:16: note: in call to 'foo(4)' 32 | static_assert (foo (4) == 11); | ^~~~~~~ <source>:33:16: error: static assertion expression is not an integral constant expression 33 | static_assert (foo (42) == 11); | ^~~~~~~~~~~~~~ <source>:23:7: note: unimplemented constexpr lambda feature: captures not currently allowed (coming soon!) 23 | s.a = 5; | ^ <source>:33:16: note: in call to 'foo(42)' 33 | static_assert (foo (42) == 11); | ^~~~~~~~ 2 errors generated. (though that shows that when using case 4: default: return 0; instead of the case 4/default in the source), clang++ accepts it.
Though, we do accept e.g. struct S { int a, b; }; constexpr int foo (int x) { if (x == 6) goto l1; { int i; i = 6; l1: i = 4; return i; } } static_assert (foo (1) == 4); for -std=c++23.