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

I wonder if the following violate the Standard

67 views
Skip to first unread message

Roli Roger

unread,
Apr 12, 2013, 12:35:06 AM4/12/13
to
there is two declaration in same scope: [1]


struct foo
{
int bar;
};
struct foo
{
int bar;
};

or it may be this: [2]
struct foo
{
int bar;
};
enum foo
{
int bar;
};


standard says in 6.7p3 that:
"If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except that:
—atypedef name may be redefined to denote the same type as it currently does,
provided that type is not a variably modified type;
—tags may be redeclared as specified in 6.7.2.3."

As far as I'm concerned, it proves that [1] is legal.

somebody might see from 6.7.2.3p1 that:
" A specific type shall have its content defined at most once."

But, still my point, tag is not a type. It just a "tag" which represents a struct/union/enum type whether complete or not. So, a look-like "redefinition to foo" just redeclare the tag itself.




In addition, 6.7.2.3p4 mentions that:
"All declarations of structure, union, or enumerated types that have the same scope and use the same tag declare the same type."

I don't know that the "same type" means, does it corrsponding the same word as specify in 6.7.2.3p2:
"Where two declarations that use the same tag declare the same type, they shall both use the same choice of struct, union,or enum"

if so, [2] is illegal, and maybe legal instead.

Roli Roger

unread,
Apr 12, 2013, 12:44:20 AM4/12/13
to
oh sorry , many syntax error in use of English, pardon me :)

Tim Rentsch

unread,
Apr 12, 2013, 10:23:15 AM4/12/13
to
Roli Roger <sts...@gmail.com> writes:

> there is two declaration in same scope: [1]
>
>
> struct foo
> {
> int bar;
> };
> struct foo
> {
> int bar;
> };
>
> or it may be this: [2]
> struct foo
> {
> int bar;
> };
> enum foo
> {
> int bar;
> };
>
>
> standard says in 6.7p3 that:
>
> "If an identifier has no linkage, there shall be no more than
> one declaration of the identifier (in a declarator or type
> specifier) with the same scope and in the same name space,
> except that: *atypedef name may be redefined to denote the
> same type as it currently does, provided that type is not a
> variably modified type; *tags may be redeclared as specified
> in 6.7.2.3."
>
> As far as I'm concerned, it proves that [1] is legal.
>
> somebody might see from 6.7.2.3p1 that:
>
> " A specific type shall have its content defined at most
> once."
>
> But, still my point, tag is not a type. It just a "tag" which
> represents a struct/union/enum type whether complete or not. So,
> a look-like "redefinition to foo" just redeclare the tag itself.
>
> In addition, 6.7.2.3p4 mentions that:
>
> "All declarations of structure, union, or enumerated types
> that have the same scope and use the same tag declare the same
> type."
>
> I don't know that the "same type" means, does it corrsponding the
> same word as specify in 6.7.2.3p2:
>
> "Where two declarations that use the same tag declare the same
> type, they shall both use the same choice of struct, union,or
> enum"
>
> if so, [2] is illegal, and maybe legal instead.

If we have the following source file (ie, translation unit)

struct foo { int bar; }; /* one */
struct foo { int bar; }; /* two */

the line marked "one" does three things:

1. It creates a new type (let's call it "type X");
2. it declares the tag 'foo' and associates it with
type X;
3. it defines the contents of type X.

The line marked "two" behaves slightly differently, because the
tag 'foo' has already been declared (and therefore associated
with some type); namely,

1. It discovers the previously created type X by looking
up 'foo' in the struct/union/enum tag namespace;
2. it re-declares the tag 'foo' (which is legal);
3. it defines the contents of type X.

The last of these actions runs afoul of 6.7.2.3 p1, which is
listed under a 'Constraints' heading. This means the example you
give as [1] is a constraint violation, and must result in a
diagnostic.

The example you give as [2], with enum, would behave as above for
the struct declaration; then, on encountering 'enum foo', would
discover the type previously created by the struct declaration,
see that the previously created type is a struct type, and hence
run afoul of 6.7.2.3 p4, since 'enum' is not the same as 'struct',
and the type created for the struct declaration is (obviously) a
struct type.

Incidentally, the enum declaration in [2] also has a syntax error.
If 'enum' were changed to 'union' that would eliminate the syntax
error (and present the same question as what you were asking about).

Roli Roger

unread,
Apr 12, 2013, 10:03:12 PM4/12/13
to
> The line marked "two" behaves slightly differently, because the
>
> tag 'foo' has already been declared (and therefore associated
>
> with some type); namely,
>
>
>
> 1. It discovers the previously created type X by looking
>
> up 'foo' in the struct/union/enum tag namespace;
>
> 2. it re-declares the tag 'foo' (which is legal);
>
> 3. it defines the contents of type X.
>
>
>


I'm sorry, in your opinion, it seems this is legal?

struct s1 { struct s2 *s2p; /*... */ }; // D1
struct s2 { struct s1 *s1p; /*... */ }; // D2

within D1:
1. s2 declare a incomplete type "sruct s2"

within D2:
1. it find previous type "struct s2"
2. it defines the content of that type

Tim Rentsch

unread,
Apr 13, 2013, 2:16:42 PM4/13/13
to
Yes, this program source is allowed by the Standard, and
behaves as you describe, assuming these are the first
declarations for these structures.

However, note the qualifying assumption. Here is a
similar but significantly different example:

struct s2; /* [A] */

int
some_function(){
struct s1 { struct s2 *s2p; }; /* [B] */
struct s2 { struct s1 *s1p; }; /* [C] */
return 0;
}

In this example using 'struct s2' in [B] refers to the type
created by the declaration at [A]. The declaration at [C]
creates a new type, distinct from the type created at [A],
but also referred to as 'struct s2', because of scoping
rules. This behavior is analogous to what happens a local
variable hides a global variable of the same name. With
types, however, it's easier for there to be a subtle bug,
because "using" a type like 'struct s2' (eg, in the line
shown at [B]) has the effect of creating a new type if
there is no previous declaration of the tag in scope, but
using the existing type if there is a previous declaration
in scope. Does that all make sense?
0 new messages