23

I've stumbled upon some weird behavior for which I couldn't find any info online. If I initialize a boolean array like this:

 bool condition[10] = {true,[5]=true};

I get the output I expect, first and sixth values are true while others are false. But if I write following snippet:

 bool condition[10] = {true,condition[5]=true};

I get first, SECOND and sixth values as true. I assume it's some kind of undefined behavior but I'd like someone more knowledgeable than me to explain to me what's going on.

I'm compiling with extra warning flags, using GCC and "-std=gnu99", and I'm not getting any errors.

10
  • The value of the expression can be used to initializer in C99. condition[5] also is available at this timing. Commented Aug 24, 2014 at 9:25
  • 1
    Yeah, but shouldn't it just flip second value and stop there? Why is it flipping 6th or whichever value i specify on top of it(as if I'm typing {true,condition[5],[5]=true})? Commented Aug 24, 2014 at 9:36
  • 5
    Again, you explicitly set condition[5]=true ... that's why it's true. You also set condition[1] to true by initializing it with a true value. "To me it looked as if for example both IF and ELSE were executed at same time. " -- No, you're just not thinking about this clearly. As ouah has explained, the setting of condition[5] can happen after the array is initialized (as is the case for you), or not ... it's underspecified by the standard. Commented Aug 24, 2014 at 9:55
  • 1
    I see, so basically condition[5]=true is setting first value to true and then doing what its supposed to do. Thanks, I couldn't wrap my mind around it,I guess I need my morning coffee to function! Commented Aug 24, 2014 at 10:01
  • 3
    condition[5]=true is an assignment. It assigns the value true to condition[5]. It also yields the value true, which is used to initialize condition[1]. Commented Aug 24, 2014 at 22:45

3 Answers 3

20

C says that:

(C11, 6.7.9p23) "The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified."

and in C99

(C99, 6.7.8p23) "The order in which any side effects occur among the initialization list expressions is unspecified."

That means that the declaration

    bool condition[10] = {true,condition[5]=true};

can have the same behavior:

    bool condition[10] = {true, 1};

or as

    bool condition[10] = {true, 1, [5] = true};

whether condition[5] = true evaluation is done before or after the 0 initialization of the array members.

EDIT: there is a case of unspecified initialization order of array elements in Defect Report #208. The case is different because in the DR example there are two initializers for a single element.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/9899tc1/n32074.htm

int a [2] = { f (0), f (1), [0] = f (2) };

It was the intention of WG14 that the call f(0) might, but need not, be made when a is initialized. If the call is made, the order in which f(0) and f(2) occur is unspecified (as is the order in which f(1) occurs relative to both of these). Whether or not the call is made, the result of f(2) is used to initialize a[0].

Sign up to request clarification or add additional context in comments.

21 Comments

Ok that answers it. One more question, why is condition[5]=true evaluated twice?
I think your quote only applies to the side effects of all the initializers among each other, not to the ordering of the those effects with respect to the initialization itself?
Want to hazard a guess about condition[10] = { true, condition[0]=false }?
I think @KerrekSB is right: It is unspecified whether true or condition[5]=true is evaluated first, but as they don't affect each other, it doesn't matter. [0] will be set to true and [1] will be set to the result of condition[5]=true, and as an assignment as an expression has the value assigned, [5]=true happens before [1]=true, and [0]=true habbens before or after that.
@JimBalter Right, in this case the result is probably unspecified.
|
10

That is a nice little puzzle. I think ouah got it, but more explanation would probably help. I think condition[5]=true is not a designated initializer. It is an expression, which evaluates to true as usual. Since that expression is in the second spot, true gets assigned to to condition[1]. Also, as a side-effect of the expression, condition[5] gets set to true.

Comments

-1

Thats Because the value is really 6 not a return of 5 0 or[0] counts as a number 0,1,2,3,4,5... 0 is 1, 1 is 2, 2 is 3, 3 is 4, 4 is 5, 5 is 6

2 Comments

This doesn't make any sense, and zero-based indexing has nothing to do with what is going on here, but I think that you misread the question. OP understands and expects that condition[5] should be true, and that this is the sixth element of the array. What has OP confused it that condition[1] was also set to true when they thought that they had only set condition[0] and condition[5] to true.
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.