operating system

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

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

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

int f() { ... } switch (f()) { case ...; case ...; } 
+53
c ++ standards language-lawyer
Jul 03 '15 at 11:52
source share
6 answers

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

First we have

The condition must be an integer type, an enumeration type, or a class type.

[6.4.2 (1)] (unlabeled material does not apply here) and

The value of the condition that is the expression is the value of Expression

[6.4 (4)]. Besides,

The meaning of the condition will simply be called a “condition” in which use is explicit.

[6.4 (4)] This means that in our case the “condition” is simply an equal value of type int , not f . f used only to determine the value of a condition. Now that control reaches the switch

his condition is evaluated

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

compared to each case constant

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

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

+36
Jul 03 '15 at 12:13
source share
— -

Reading N4296

Page 10 para 14:

Each value calculation and side effect associated with the full expression are sequenced before each value calculation and side effect associated with the next full expression that needs to be evaluated.

When I read the first line of the paragraph. 10 (above this):

A full expression is an expression that is not a subexpression of another expression.

I must assume that the condition of the switch is a complete expression, and each condition expression is a full expression (albeit trivial when executed).

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

Thus, in this reading, the switch evaluation must be performed before evaluating the case constants.

As always, many points come down to a tortuous reading of the specification in order to arrive at an obvious conclusion.

If I consider this proposal, I would suggest the following amendment (in bold ):

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

+5
Jul 03 '15 at 12:56
source share

Yes, an expression is evaluated only once when the switch statement is executed:

§ 6.4 Selection operations

4 [...] The value of the condition, which is the expression, is the value of the expression [...] The value of the condition will be called simply a “condition”, where the use is explicit.

This means that the expression is evaluated, and its value is considered a condition , which must be evaluated against each case .

+3
Jul 03 '15 at 12:20
source share

Section 6.4.4:

... The value of the condition, which is an expression, is the value of the expression contextually converted to bool for statements other than switch; ... The value of the condition will simply be called a "condition" in which use is explicit

In my understanding, the above quote is equivalent to the following pseudocode:

 switchCondition := evaluate(expression) 

Now add your quote

... his condition is evaluated and compared with each case constant.

Which should be translated into:

 foreach case in cases if case.constant == switchCondition goto case.block 

So yes, it seems so.

+2
Jul 03 '15 at 12:11
source share

Does this code print hello once or twice?

 int main() { printf("hello\n"); } 

Well, I think the answer lies in a more general understanding of what the standard describes, and not in the specific wording of the switch .

In accordance with the Execution of the program [intro.execution], the standard describes the behavior of an abstract machine that runs a program analyzed by C ++ grammar. It does not define what “abstract machine” or “performs” means, but it is assumed that they mean their obvious concepts of computer science, that is, a computer that goes through an abstract syntax tree and evaluates each part of it in accordance with the semantics described in the standard . This means that if you wrote something once, then when the execution reaches this point, it is evaluated only once.

A more relevant question is “when can an implementation evaluate something different than what is written in the program”? To do this, there is an as-if rule and a bunch of undefined behavior that allow the implementation to deviate from this abstract interpretation.

+2
Jul 03 '15 at 12:35
source share

An expression is guaranteed that is evaluated only once by the control flow. This is justified in standard N4431 §6.4.2 / 6. Switch statement [stmt.switch] ( Active hit ):

case and labels by default do not by themselves change the stream, which continues to pass through such labels unhindered. To exit the switch, see gap, 6.6.1. [Note: usually, the substance that the switch item is compound and random, and default labels appear on the top-level operators contained in the (compound) substance, but this is not required. Declarations may appear in the substitution of the switch-statement statement. - final note]

0
Jul 03 '15 at 12:14
source share



All Articles