Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: struct declaration in for loop

Reply
Thread Tools

Re: struct declaration in for loop

 
 
James Kuyper
Guest
Posts: n/a
 
      07-05-2013
On 07/05/2013 11:38 AM, Keith Thompson wrote:
> Tim Rentsch <(E-Mail Removed)> writes:
>> Keith Thompson <(E-Mail Removed)> writes:
>>> Noob <root@127.0.0.1> writes:
>>>> william wrote:
>>>>> GCC accepts the following code, but clang chokes with "error:
>>>>> declaration of non-local variable in 'for' loop".
>>>>>
>>>>> #include <stdio.h>
>>>>>
>>>>> int main(void) {
>>>>> for (struct { int y; } x = { 0 }; x.y < 10; x.y++) {
>>>>> printf("x.y:%d\n", x.y);
>>>>> }
>>>>>
>>>>> return 0;
>>>>> }
>>>>>
>>>>> I cannot find any justification in the standard for clang to
>>>>> reject that code. It will accept this variation, however:
>>>>>
>>>>> struct foo { int y; };
>>>>>
>>>>> for (struct foo x = { 0 }; x.y < 10; x.y++)

....
>>> Both C99 and C11 have the following constraint in 6.8.5p3:
>>>
>>> The declaration part of a for statement shall only declare
>>> identifiers for objects having storage class auto or register.

....
>>> I suppose that's ambiguous. If it means that any objects declared
>>> must have storage class auto or register, then your code is ok.
>>> If it means that any declared identifiers must be for objects with
>>> storage class auto or register, then the declaration of the struct
>>> member "y" violates the constraint. "y" is probably the "non-local
>>> variable" referred to by clang's error message.

>>
>> Yes, unfortnately, it can be read either way.
>>
>> Surely the first interpretation is what was intended, and the
>> second interpretation is just accidental consequence of the
>> wording used. But it looks like the possibility for confusion
>> is high enough that it's worth bringing up in comp.std.c, or
>> emailing Larry Jones, or both.

>
> So you think that it's intended to permit declarations of things
> other than objects in a for loop header? The restriction to a single
> declaration makes it difficult to *usefully* declare anything other
> than an object; I can't think of a non-contrived example.
>
> By your interpretation, if I understand you correctly, this would
> be legal (I posted this elsethread):
>
> #include <stdio.h>
> int main(void) {
> int i = 0;
> for (typedef int ignored; i < 10; i ++) {
> printf("%d\n", i);
> }
> return 0;
> }


"typedef int ignored" doesn't declare an object of any kind. It does
declare a typedef, which seems to me to clearly be a violation of 6.8.5p3.

struct {int y;} x is the declaration of an object with automatic storage
duration, namely 'x'. I see "int y" simply as part of the specification
of the type of x, and not directly a declaration of a object in it's own
right. However, if you believe that it should be considered a
declaration of the 'y' sub-object of the object 'x', it still declares
an object with automatic storage duration. So, I still don't see that as
a violation of 6.8.5p3. I'd feel differently if it declared a tag for
the struct, rather than a member, because in that case it's also
declaring a type. However, a member is inherently part of the object
it's a member of, and has the same storage duration.

It's not entirely clear to me that your interpretation is wrong, but
that's not how I understand it.

 
Reply With Quote
 
 
 
 
Tim Rentsch
Guest
Posts: n/a
 
      07-05-2013
Keith Thompson <(E-Mail Removed)> writes:

> Tim Rentsch <(E-Mail Removed)> writes:
>> Keith Thompson <(E-Mail Removed)> writes:
>>> Noob <root@127.0.0.1> writes:
>>>> william wrote:
>>>>> GCC accepts the following code, but clang chokes with "error:
>>>>> declaration of non-local variable in 'for' loop".
>>>>>
>>>>> #include <stdio.h>
>>>>>
>>>>> int main(void) {
>>>>> for (struct { int y; } x = { 0 }; x.y < 10; x.y++) {
>>>>> printf("x.y:%d\n", x.y);
>>>>> }
>>>>>
>>>>> return 0;
>>>>> }
>>>>>
>>>>> I cannot find any justification in the standard for clang to
>>>>> reject that code. It will accept this variation, however:
>>>>>
>>>>> struct foo { int y; };
>>>>>
>>>>> for (struct foo x = { 0 }; x.y < 10; x.y++)
>>>>>
>>>>> Is clang wrong? Is GCC overly permissive?
>>>>
>>>> Are you asking for C99 or C11 or both?
>>>
>>> Why do you think it matters?
>>>
>>> Both C99 and C11 have the following constraint in 6.8.5p3:
>>>
>>> The declaration part of a for statement shall only declare
>>> identifiers for objects having storage class auto or register.
>>>
>>> (It's easy to miss, since it's in section 6.8.5, "Iteration
>>> statements", not 6.8.5.3, "The for statement".)

>>
>> I'm impressed! Kudos for finding this.
>>
>>> I suppose that's ambiguous. If it means that any objects declared
>>> must have storage class auto or register, then your code is ok.
>>> If it means that any declared identifiers must be for objects with
>>> storage class auto or register, then the declaration of the struct
>>> member "y" violates the constraint. "y" is probably the "non-local
>>> variable" referred to by clang's error message.

>>
>> Yes, unfortnately, it can be read either way.
>>
>> Surely the first interpretation is what was intended, and the
>> second interpretation is just accidental consequence of the
>> wording used. But it looks like the possibility for confusion
>> is high enough that it's worth bringing up in comp.std.c, or
>> emailing Larry Jones, or both.

>
> So you think that it's intended to permit declarations of things
> other than objects in a for loop header?


No, that was confusing, and I'm glad you asked for clarification.

> The restriction to a single
> declaration makes it difficult to *usefully* declare anything other
> than an object; I can't think of a non-contrived example.
>
> By your interpretation, if I understand you correctly, this would
> be legal (I posted this elsethread):
>
> #include <stdio.h>
> int main(void) {
> int i = 0;
> for (typedef int ignored; i < 10; i ++) {
> printf("%d\n", i);
> }
> return 0;
> }
>
> Both gcc and clang reject it.


In my reading it is correct to reject this program, because the
storage-class specifier used ('typedef') is not allowed.

The wording used in 6.8.5 p3 is a little bit careless. Taken
literally, it would allow only the _declaring_ of variables, but
not _initializing_ them. That is obviously wrong.

What I think is meant is something like what is said for
parameter declarations in a prototype, eg,

The outermost declaration-specifiers of a for statement shall
have no storage-class specifier other than auto or register.

That meaning (even if the phrasing is a little awkward) is
consistent with the C99 Rationale document, which says

To simplify the syntax, each loop is limited to a single
declaration (though this can declare several variables),
and these must have auto or register storage class.

Bottom line: I believe the gcc interpretation is right, and the
clang interpretation (in that one case) is wrong. And the
wording used in 6.8.5 p3 definitely needs revision, especially
since at least one implementation has interpreted it wrongly.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      07-05-2013
Eric Sosman <(E-Mail Removed)> writes:
> On 7/5/2013 11:31 AM, Keith Thompson wrote:
>> Keith Thompson <(E-Mail Removed)> writes:
>>> James Kuyper <(E-Mail Removed)> writes:
>>>> On 07/04/2013 04:06 PM, Keith Thompson wrote:
>>>>> Noob <root@127.0.0.1> writes:
>>>>>> william wrote:
>>>>>>> GCC accepts the following code, but clang chokes with "error: declaration of
>>>>>>> non-local variable in 'for' loop".
>>>>>>>
>>>>>>> #include <stdio.h>
>>>>>>>
>>>>>>> int main(void) {
>>>>>>> for (struct { int y; } x = { 0 }; x.y < 10; x.y++) {
>>>>>>> printf("x.y:%d\n", x.y);
>>>>>>> }
>>>>>>>
>>>>>>> return 0;
>>>>>>> }
>>>>>>>
>>>>>>> I cannot find any justification in the standard for clang to reject that
>>>>>>> code. It will accept this variation, however:
>>>>>>>
>>>>>>> struct foo { int y; };
>>>>>>>
>>>>>>> for (struct foo x = { 0 }; x.y < 10; x.y++)
>>>>>>>
>>>>>>> Is clang wrong? Is GCC overly permissive?
>>>>>>
>>>>>> Are you asking for C99 or C11 or both?
>>>>>
>>>>> Why do you think it matters?
>>>>>
>>>>> Both C99 and C11 have the following constraint in 6.8.5p3:
>>>>>
>>>>> The declaration part of a for statement shall only declare
>>>>> identifiers for objects having storage class auto or register.
>>>>>
>>>>> (It's easy to miss, since it's in section 6.8.5, "Iteration
>>>>> statements", not 6.8.5.3, "The for statement".)
>>>>>
>>>>> I suppose that's ambiguous. If it means that any objects declared
>>>>> must have storage class auto or register, then your code is ok.
>>>>> If it means that any declared identifiers must be for objects with
>>>>> storage class auto or register, then the declaration of the struct
>>>>> member "y" violates the constraint. "y" is probably the "non-local
>>>>> variable" referred to by clang's error message.
>>>>
>>>> I "know" that the storage duration for x.y depends only upon the
>>>> declaration of x, which has automatic storage duration. However, I
>>>> haven't found a clause that says so explicitly. The closest I've come is:
>>>>
>>>> "An object whose identifier is declared with no linkage and without the
>>>> storage-class specifier static has automatic storage duration,".
>>>>
>>>> However, but it takes two identifiers to identify x.y so I'm not how
>>>> 6.8.5.3 applies. I believe is should allow such declarations.
>>>
>>> The issue isn't the storage duration of x.y, which is clearly automatic.
>>> The issue is that `int y;` doesn't declare an object; it declares a
>>> member. It seems that the authors of gcc and clang disagree on whether
>>> such a declaration is permitted by 6.5.8p3.
>>>
>>> I'll ask in comp.std.c.

>>
>> I'm holding off on the comp.std.c post for a bit, because I discovered
>> this:
>>
>> #include <stdio.h>
>> int main(void) {
>> int i = 0;
>> for (typedef int ignored; i < 10; i ++) {
>> printf("%d\n", i);
>> }
>> return 0;
>> }
>>
>> gcc 4.8.0, invoked with "-std=c99 -pedantic", rejects this with:
>>
>> c.c: In function 'main':
>> c.c:4:5: error: declaration of non-variable 'ignored' in 'for' loop
>> initial declaration
>> for (typedef int ignored; i < 10; i ++) {
>> ^
>>
>> clang 3.0 with the same arguments rejects it with:
>>
>> c.c:4:22: error: declaration of non-local variable in 'for' loop
>> for (typedef int ignored; i < 10; i ++) {
>> ^
>> 1 error generated.
>>
>> clang's error message is poorly worded; it's not a variable declaration
>> at all. But the point is that gcc and clang agree that a non-variable
>> declaration is not permitted in a for loop header.

>
> This much makes sense, I think. The storage class `typedef'
> is neither `auto' nor `register', so both compilers are right to
> reject the construct.
>
> Here's a variation that might shed some light:
>
> #include <stdio.h>
> int main(void) {
> int i = 0;
> for (struct {int :8;}; i < 10; i ++) {
> printf("%d\n", i);
> }
> return 0;
> }
>
> I don't have clang, but gcc versions 3.4.4 and 4.4.1 accept it,
> albeit with warnings. It looks more and more like the presence
> of an identifier inside the declared struct may be the crux.


This provides some insight into how gcc and clang operate, but it's
complicated by N1256 6.7.2.1p7:

If the struct-declaration-list contains no named members,
the behavior is undefined.

and the nearly equivalent N1570 6.7.2.1p8:

If the struct-declaration-list does not contain any named
members, either directly or via an anonymous structure or
anonymous union, the behavior is undefined.

(I have no idea why a struct or union declaration with no named
members causes undefined behavior rather than simply being a
constraint violation.)

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      07-05-2013
In comp.lang.c James Kuyper <(E-Mail Removed)> wrote:
> On 07/05/2013 11:38 AM, Keith Thompson wrote:


(snip)
>> By your interpretation, if I understand you correctly, this would
>> be legal (I posted this elsethread):


>> #include <stdio.h>
>> int main(void) {
>> int i = 0;
>> for (typedef int ignored; i < 10; i ++) {
>> printf("%d\n", i);
>> }
>> return 0;
>> }


> "typedef int ignored" doesn't declare an object of any kind.
> It does declare a typedef, which seems to me to clearly be a
> violation of 6.8.5p3.


> struct {int y;} x is the declaration of an object with
> automatic storage duration, namely 'x'. I see "int y" simply
> as part of the specification of the type of x, and not directly
> a declaration of a object in it's own right.


Might be different if it was

struct z {int y;} x;

which also declares z as a struct name.

> However, if you believe that it should be considered a
> declaration of the 'y' sub-object of the object 'x', it still
> declares an object with automatic storage duration.
> So, I still don't see that as a violation of 6.8.5p3.
> I'd feel differently if it declared a tag for the struct,
> rather than a member, because in that case it's also
> declaring a type. However, a member is inherently part of the
> object it's a member of, and has the same storage duration.


I agree.

-- glen
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-05-2013
Tim Rentsch <(E-Mail Removed)> writes:
> Keith Thompson <(E-Mail Removed)> writes:

[...]
>> The restriction to a single
>> declaration makes it difficult to *usefully* declare anything other
>> than an object; I can't think of a non-contrived example.
>>
>> By your interpretation, if I understand you correctly, this would
>> be legal (I posted this elsethread):
>>
>> #include <stdio.h>
>> int main(void) {
>> int i = 0;
>> for (typedef int ignored; i < 10; i ++) {
>> printf("%d\n", i);
>> }
>> return 0;
>> }
>>
>> Both gcc and clang reject it.

>
> In my reading it is correct to reject this program, because the
> storage-class specifier used ('typedef') is not allowed.
>
> The wording used in 6.8.5 p3 is a little bit careless. Taken
> literally, it would allow only the _declaring_ of variables, but
> not _initializing_ them. That is obviously wrong.
>
> What I think is meant is something like what is said for
> parameter declarations in a prototype, eg,
>
> The outermost declaration-specifiers of a for statement shall
> have no storage-class specifier other than auto or register.
>
> That meaning (even if the phrasing is a little awkward) is
> consistent with the C99 Rationale document, which says
>
> To simplify the syntax, each loop is limited to a single
> declaration (though this can declare several variables),
> and these must have auto or register storage class.
>
> Bottom line: I believe the gcc interpretation is right, and the
> clang interpretation (in that one case) is wrong. And the
> wording used in 6.8.5 p3 definitely needs revision, especially
> since at least one implementation has interpreted it wrongly.


I picked "typedef" just because it's a declaration that doesn't
declare an object. The fact that it's treated as a storage-class
specifier (for syntactic convenience) confused the point I was
trying to make.

My speculation/guess about the intent of 6.8.5p3:

The declaration part of a for statement shall only declare
identifiers for objects having storage class auto or register.

is that a declaration in a for loop header must only declare objects,
and those objects must only have storage class auto or register.

That's different from what you're saying, which is that such a
declaration cannot have a storage class other than register or auto --
but (implicitly) it needn't be an object declaration. By your
interpretation, which is consistent with the wording BTW, this would be
legal:

int i = 0;
for (void foo(void); i < 10; i ++) {
printf("%d\n", i);
}

since a function has no storage class.

My interpretation is not based entirely on the wording in the
standard; it also accounts for (what I think is) the intended use
of declarations in for loop headers, namely defining loop iteration
variables and keeping them local to the loop. I tend to think that
non-object declarations in for loop headers are not particularly
useful, and are better placed in a scope surrounding the loop.
It might be useful to define a type and then an object of that
type, but that would require multiple declarations, which are not
permitted, so the type declaration has to go elsewhere.

There would be something to be said for allowing *any* declaration,
but 6.8.5p3 is clearly restrictive, and IMHO it makes the most
sense to permit only object declarations with automatic or register
storage class.

The most nearly non-contrived example of something other than an
object declaration is something like this:

for (enum { zero, one, two } i = zero; i <= two; i ++) {
/* ... */
}

but even if that's legal (both gcc and clang reject it), I'd still
rather declare the enum type outside the loop. (I think it's illegal
because it declares "zero", "one", and "two", which are not objects.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-05-2013
James Kuyper <(E-Mail Removed)> writes:
> On 07/05/2013 11:38 AM, Keith Thompson wrote:

[...]
>> By your interpretation, if I understand you correctly, this would
>> be legal (I posted this elsethread):


(The above was addressed to Tim Rentsch.)

>> #include <stdio.h>
>> int main(void) {
>> int i = 0;
>> for (typedef int ignored; i < 10; i ++) {
>> printf("%d\n", i);
>> }
>> return 0;
>> }

>
> "typedef int ignored" doesn't declare an object of any kind. It does
> declare a typedef, which seems to me to clearly be a violation of 6.8.5p3.
>
> struct {int y;} x is the declaration of an object with automatic storage
> duration, namely 'x'. I see "int y" simply as part of the specification
> of the type of x, and not directly a declaration of a object in it's own
> right. However, if you believe that it should be considered a
> declaration of the 'y' sub-object of the object 'x', it still declares
> an object with automatic storage duration. So, I still don't see that as
> a violation of 6.8.5p3. I'd feel differently if it declared a tag for
> the struct, rather than a member, because in that case it's also
> declaring a type. However, a member is inherently part of the object
> it's a member of, and has the same storage duration.
>
> It's not entirely clear to me that your interpretation is wrong, but
> that's not how I understand it.


`int y;` doesn't declare an object. `struct {int y;} x;` obviously does
declare an object `x`; it also declares another object `x.y`, which is a
subobject of `x`.

The problem is that `int y;` declares a struct member, and by at least
one interpretation that's not allowed in a for loop header; only object
declarations are allowed, and only with automatic or register storage
class.

(On the other hand, `int y;` is not syntactically a "declaration", which
probably muddies the waters even more.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      07-05-2013
Keith Thompson <(E-Mail Removed)> writes:

> Tim Rentsch <(E-Mail Removed)> writes:
>> Keith Thompson <(E-Mail Removed)> writes:

> [...]
>>> The restriction to a single
>>> declaration makes it difficult to *usefully* declare anything other
>>> than an object; I can't think of a non-contrived example.
>>>
>>> By your interpretation, if I understand you correctly, this would
>>> be legal (I posted this elsethread):
>>>
>>> #include <stdio.h>
>>> int main(void) {
>>> int i = 0;
>>> for (typedef int ignored; i < 10; i ++) {
>>> printf("%d\n", i);
>>> }
>>> return 0;
>>> }
>>>
>>> Both gcc and clang reject it.

>>
>> In my reading it is correct to reject this program, because the
>> storage-class specifier used ('typedef') is not allowed.
>>
>> The wording used in 6.8.5 p3 is a little bit careless. Taken
>> literally, it would allow only the _declaring_ of variables, but
>> not _initializing_ them. That is obviously wrong.
>>
>> What I think is meant is something like what is said for
>> parameter declarations in a prototype, eg,
>>
>> The outermost declaration-specifiers of a for statement shall
>> have no storage-class specifier other than auto or register.
>>
>> That meaning (even if the phrasing is a little awkward) is
>> consistent with the C99 Rationale document, which says
>>
>> To simplify the syntax, each loop is limited to a single
>> declaration (though this can declare several variables),
>> and these must have auto or register storage class.
>>
>> Bottom line: I believe the gcc interpretation is right, and the
>> clang interpretation (in that one case) is wrong. And the
>> wording used in 6.8.5 p3 definitely needs revision, especially
>> since at least one implementation has interpreted it wrongly.

>
> I picked "typedef" just because it's a declaration that doesn't
> declare an object. The fact that it's treated as a storage-class
> specifier (for syntactic convenience) confused the point I was
> trying to make.
>
> My speculation/guess about the intent of 6.8.5p3:
>
> The declaration part of a for statement shall only declare
> identifiers for objects having storage class auto or register.
>
> is that a declaration in a for loop header must only declare
> objects, and those objects must only have storage class auto or
> register.
>
> That's different from what you're saying, which is that such a
> declaration cannot have a storage class other than register or auto
> -- but (implicitly) it needn't be an object declaration.


Unfortunately what I was trying to say was not quite in sync with
the phrasing I used to express it.

> By your interpretation, which is consistent with the wording BTW,
> this would be legal:
>
> int i = 0;
> for (void foo(void); i < 10; i ++) {
> printf("%d\n", i);
> }
>
> since a function has no storage class.


My intended meaning would not allow that. You're right that the
wording I gave would allow it. That happened because it didn't
occur to me to consider function declarations, which probably
also explains why the wording used in the Standard is so awkward.
Let me take another stab at Standard-ese expressing my intended
meaning:

The declaration part of a for statement shall have an
init-declarator-list, if present, whose top-level declarators
declare identifiers for objects of automatic storage duration.

I'm assuming a suitable definition of "top-level declarator",
which I hope is clear enough that it doesn't need to be explained
further here (though it probably would in the Standard).

This phrasing would not allow the function declaration example
given above. It would allow all of

for( struct foo *p = 0; p; ) {}
for( struct { int i;} p = {0}; p.i; ) {}
for( struct bas { int i;} q = {0}; q.i; ) {}
for( enum { a, b, c } i = c; i; i-- ) {}
for( enum foo_e { x, y, z } j = z; j; j-- ) {}
for( int (*f)( int i, char *v[] ) = 0; f; ) {}

where 'struct foo' and 'struct bas' have not been previously
declared (and also if they have been, but that introduces no
additional information).

> My interpretation is not based entirely on the wording in the
> standard; it also accounts for (what I think is) the intended use
> of declarations in for loop headers, namely defining loop iteration
> variables and keeping them local to the loop. I tend to think that
> non-object declarations in for loop headers are not particularly
> useful, and are better placed in a scope surrounding the loop. It
> might be useful to define a type and then an object of that type,
> but that would require multiple declarations, which are not
> permitted, so the type declaration has to go elsewhere.


It is possible to define a type, in the sense of defining the
contents of a struct or union type, and also declare an object of
that type, in a single declaration. In fact a single declaration
can declare several objects of the defined type, or types which
are derived from that type -- eg a struct object, a pointer to
said type of struct, and an array of said type of struct, all in
a single declaration that also defines the type.

Clarification: I mean this is possible in an ordinary, non-for
declaration. Obviously we still aren't sure what the Standard
expects for declarations given as for-clauses.

> There would be something to be said for allowing *any* declaration,
> but 6.8.5p3 is clearly restrictive, and IMHO it makes the most
> sense to permit only object declarations with automatic or register
> storage class.


For top-level declarators, I agree with you. For declarators
other than those appearing in the top-level init-declarator-list,
I think anything allowed in a non-for declaration should also be
allowed in a for-clause declaration. (That's what I think should
be true, not necessarily what the Standard means to allow.)

Incidentally, there is no automatic storage class. Even talking
about "auto storage class" is somewhat an abuse of language,
since most declarations don't use the 'auto' specifier. The
salient property is that the objects should be of automatic
storage duration, and IMO that is how the Standard should express
it.

> The most nearly non-contrived example of something other than an
> object declaration is something like this:
>
> for (enum { zero, one, two } i = zero; i <= two; i ++) {
> /* ... */
> }
>
> but even if that's legal (both gcc and clang reject it), I'd still
> rather declare the enum type outside the loop. (I think it's
> illegal because it declares "zero", "one", and "two", which are not
> objects.)


I find gcc's behavior rather confusing. Since it allows defining
the contents of a structure type, I don't see any reason why it
should not allow the defining of an enumeration type. It seems
inconsistent. Furthermore there is this:

for( int (*f)( int i, char *v[] ) = main; f; f = 0 ) {}

This for-clause is accepted by gcc, despite the presence of two
declared identifiers ('i' and 'v') that do not declare objects.
Perhaps gcc interprets 6.8.5 p3 to mean identifiers declared
directly in the outermost current scope; that would explain
why the struct definition and function prototype are accepted,
whereas the enum definition is not, since its member identifers
survive into the currently active scope.

Two other gcc data points:

for( struct foo *p = 0; p; ) {}

is not accepted (with no previous declaration of 'struct foo'),
whereas

for( struct {int i;} *p = 0; p && p->i; ){}

is accepted. That's consistent with the idea that identifiers
that survive (directly) into the currently active scope are
required by gcc to be identifiers for objects (of automatic
storage duration).
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Triple nested loop python (While loop insde of for loop inside ofwhile loop) Isaac Won Python 9 03-04-2013 10:08 AM
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
struct declaration into another struct slocum C++ 3 04-11-2008 09:42 AM
Initialize pointer-to-struct declaration to an unnamed struct? Ehud Shapira C++ 20 06-30-2007 04:10 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments