On 4/6/2012 05:52, Keith Thompson wrote:
> Shao Miller<
sha0....@gmail.com> writes:
>> Perhaps this has come up before and I've missed it, but how does one
>> reconcile C11 6.7.9p2 and the example of 6.5.2.5p8?
>>
>> "No initializer shall attempt to provide a value for an object not
>> contained within the entity being initialized."
>>
>> "EXAMPLE 1 The file scope definition
>> int *p = (int []){2, 4};
>> initializes p to point to the first element of an array of two ints, the
>> first having the value two and the second, four. The expressions in this
>> compound literal are required to be constant. The unnamed object has
>> static storage duration."
>>
>> I'd expect the intention of the former is to disallow:
>>
>> int x;
>> int y = x = 42;
>
> Actually that's legal. The initial value assigned to y is the result of
> the assignment expression ``x = 42''. My interpretation of 6.7.9p2 is
> that the *initializer* doesn't provide a value for x; rather a side
> effect of an expression that's part of the initializer provides that
> value.
>
Hmm... I can see that if "provide" is not the same as "store". I'm
pretty sure I think I know what you mean, though: The computation of the
value of the initializer causes a value to be stored into 'x', but the
value of the initializer (once computed) does not.
Suggestion:
"The value of an initializer shall not attempt to provide a value for
an object not contained within the entity being initialized."
Or maybe:
"An initializer shall correspond to an object contained within the
entity being initialized."
> I think 6.7.9p2 is simply intended to disallow things like this:
>
> struct s { int x; int y };
> struct s obj = { 1, 2, 3 };
>
Or:
struct s { int x; struct { int y; int z; } ss; };
struct s obj = { .ss = { .x = 1, .y = 2, .z = 3 } };
>> But the initializers in '{2, 4}' are providing values for an array
>> object [obviously] not contained in the pointer object 'p'.
>>
>> Does that allow the following (at block scope, as opposed to above)?:
>>
>> int * p = *(int *[]){(int[]){2, 4}};
>
> gcc thinks so (with "-std=c99 -pedantic"); I know that doesn't really
> answer the question.
>
I guess my challenge is really with "provide". C89 had:
"There shall be no more initializers in an initializer list than
there are objects to be initialized."
I'm not entirely sure what makes the current form stronger. Perhaps
it's to allow for redundant designated intializers?
Is it to disallow the following?:
struct s { int x; int y; };
struct s obj = { .x .y = 42 };
Where:
- '42' is an initializer
- '.y' is a designator
- '.x' is a designator
- '.x .y' is a designator-list
- .x .y =' is a designation
- '.x .y = 42' is an initializer-list