C++ switch statement expression evaluation guarantee

Regarding switch the standard states the following. "When the switch statement is executed, its condition is evaluated and compared with each case constant."

Does it mean that the condition expression evaluated once and once only, and it is guaranteed by the standard for each compiler?

For example, when a function is used in the switch statement head, with a side effect.

int f() { ... }
switch (f())
{
    case ...;
    case ...;
}

Solution 1:

I think it is guaranteed that f is only called once.

First we have

The condition shall be of integral type, enumeration type, or class type.

[6.4.2 (1)] (the non-integral stuff does not apply here), and

The value of a condition that is an expression is the value of the expression

[6.4 (4)]. Furthermore,

The value of the condition will be referred to as simply “the condition” where the usage is unambiguous.

[6.4 (4)] That means in our case, the "condition" is just a plain value of type int, not f. f is only used to find the value for the condition. Now when control reaches the switch statement

its condition is evaluated

[6.4.2 (5)], i.e. we use the value of the int that is returned by f as our "condition". Then finally the condition (which is a value of type int, not f), is

compared with each case constant

[6.4.2 (5)]. This will not trigger side effects from f again.

All quotes from N3797. (Also checked N4140, no difference)

Solution 2:

Reading N4296

Page 10 para 14:

Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.

When I read the first line of para. 10 (above that):

A full-expression is an expression that is not a sub-expression of another expression.

I have to believe that the condition of a switch statement is a full-expression and each condition expression is a full expression (albeit trivial at execution).

A switch is a statement not an expression (see 6.4.2 and many other places).

So by that reading the evaluation of the switch must take place before the evaluation of the case constants.

As ever many points boil down to tortuous reading of the specification to come to an obvious conclusion.

If I peer reviewed that sentence I would propose the following amendment (in bold):

When the switch statement is executed, its condition is evaluated once per execution of the switch statement and compared with each case constant.