Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reconciliation of C11 6.7.9p2 and 6.5.2.5p8

27 views
Skip to first unread message

Shao Miller

unread,
Apr 6, 2012, 3:25:10 AM4/6/12
to
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;

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}};

Keith Thompson

unread,
Apr 6, 2012, 5:52:44 AM4/6/12
to
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.

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 };

> 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.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Shao Miller

unread,
Apr 6, 2012, 2:43:51 PM4/6/12
to
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

Jens Gustedt

unread,
Apr 6, 2012, 3:30:19 PM4/6/12
to
Am 04/06/2012 09:43 PM, schrieb Shao Miller:
> On 4/6/2012 05:52, Keith Thompson wrote:
>> Shao Miller<sha0....@gmail.com> writes:
>> "An initializer shall correspond to an object contained within the
>> entity being initialized."

in the semantics part the standard uses the terms subobject and
association of an initializer and a subobject. Perhaps could be a bit better

Each initializer shall be associated to a subobject of the current
object being initialized.

Jens

Hans-Bernhard Bröker

unread,
Apr 6, 2012, 4:41:20 PM4/6/12
to
On 06.04.2012 20:43, Shao Miller wrote:
> 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.

What makes you assume that improved strength why it was changed?

> Perhaps it's
> to allow for redundant designated intializers?

Not so much for redundant ones, but for ones that actually don't fit in
the entity being initialized.

> Is it to disallow the following?:
>
> struct s { int x; int y; };
> struct s obj = { .x .y = 42 };

Close, but not quite there yet. Think of

int a[3] = { [5] = 4; };

instead.

Jonathan Leffler

unread,
Apr 13, 2012, 3:43:35 AM4/13/12
to
On 4/6/12 12:25 AM, Shao Miller wrote:
> 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};

The initializer is a compound literal representing an array of integers.
As with any array in almost any context, it decays to a pointer to
`int` which is entirely appropriate as the initializer for an 'int *',
isn't it?

If so, there's no conflict between the example (and don't forget that
examples are non-normative) and the the rest of the standard.

> 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;
>
> 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}};


--
Jonathan Leffler #include <disclaimer.h>
Email: jlef...@earthlink.net, jlef...@us.ibm.com
Guardian of DBD::Informix v2011.0612 -- http://dbi.perl.org/
0 new messages