f



"declaration of 'foo' changes meaning from 'struct foo'"

Hello,

I am a resonably confident C programmer, but not very sure about the
dark corners of C++. Recently, I had G++ give me a strange error.

The program in question is in essence:

    struct foo {
    };

    struct bar {
        foo foo;
    };

That is, I try to declare a member variable called "foo". However, G++
complains that:

    Foo.C:5: error: declaration of `foo bar::foo'
    Foo.C:1: error: changes meaning of `foo' from `struct foo'

Changing the line to

    struct foo foo;

makes the compiler happy. However, Microsoft Visual C++ does not give
any error at all for the code.

So, which compiler is right here? If G++ is correct, what rule of C++
am I violating, and what is the reason this restriction was introduced?

Thanks in advance for any replies.

--=20
  Vilhelm Sj=F6berg

0
9/10/2005 8:27:58 PM
comp.lang.c++ 49423 articles. 7 followers. Post Follow

5 Replies
624 Views

Similar Articles

[PageSpeed] 8

<vilhelm.sjoberg@gmail.com> wrote in message
news:1126384078.479549.120330@g47g2000cwa.googlegroups.com...

| The program in question is in essence:
|
|    struct foo {
|    };
|
|    struct bar {
|        foo foo;
|    };
<snip>
| So, which compiler is right here? If G++ is correct, what rule of C++
| am I violating, and what is the reason this restriction was
introduced?

Which compiler is correct is not the issue here. A type is not a
variable. Perhaps the best solution involves a better identifier
convention. The last issue you want to deal with (whether you wrote the
code or you are a client of the code) is whether foo refers to the type
or to the variable.

struct Foo
{
};

struct Bar
{
    Foo foo;
};

int main()
{
    Bar bar;
}

I'ld rather not rely on a particular compiler's warnings or errors to
follow a set of rules as fundamental as a clear naming convention.


0
pj7016 (88)
9/10/2005 10:31:40 PM
vilhelm.sjoberg@gmail.com wrote:
> Hello,
>
> I am a resonably confident C programmer, but not very sure about the
> dark corners of C++. Recently, I had G++ give me a strange error.
>
> The program in question is in essence:
>
>     struct foo {
>     };
>
>     struct bar {
>         foo foo;
>     };
>
> That is, I try to declare a member variable called "foo". However, G++
> complains that:
>
>     Foo.C:5: error: declaration of `foo bar::foo'
>     Foo.C:1: error: changes meaning of `foo' from `struct foo'
>
> Changing the line to
>
>     struct foo foo;
>
> makes the compiler happy. However, Microsoft Visual C++ does not give
> any error at all for the code.
>
> So, which compiler is right here? If G++ is correct, what rule of C++
> am I violating, and what is the reason this restriction was introduced?

I tried it on VC++ and EDG at dinkumware.com as well as at Comeau
online. None give an error, so I suspect g++ is less conformant at this
point. That said, it is *bad* style to try something like that.

Cheers! --M

0
mlimber (2146)
9/11/2005 12:11:05 AM
On 10 Sep 2005 17:11:05 -0700, "mlimber" <mlimber@gmail.com> wrote:

>> Changing the line to
>>
>>     struct foo foo;
>>
>> makes the compiler happy. However, Microsoft Visual C++ does not give
>> any error at all for the code.
>>
>> So, which compiler is right here? If G++ is correct, what rule of C++
>> am I violating, and what is the reason this restriction was introduced?
>
>I tried it on VC++ and EDG at dinkumware.com as well as at Comeau
>online. None give an error, so I suspect g++ is less conformant at this
>point. That said, it is *bad* style to try something like that.

I think you're right. The standard mentions other occasions where reusing an
already-declared identifier in a different context is acceptable:

7.1

2 The longest sequence of decl-specifiers that could possibly be a type name
is taken as the decl-specifier-seq of a declaration. The sequence shall be
self-consistent as described below.

[Example:
    typedef char* Pc;
    static Pc; // error: name missing

Here, the declaration static Pc is ill-formed because no name was specified
for the static variable of type Pc. To get a variable called Pc, a
type-specifier (other than const or volatile) has to be present to indicate
that the typedef-name Pc is the name being (re)declared, rather than being
part of the decl-specifier sequence. For another example,

    void f(const Pc); // void f(char* const) (not const char*)
    void g(const int Pc); // void g(const int)
�end example]

3 [Note: since signed, unsigned, long, and short by default imply int, a
type-name appearing after one of those specifiers is treated as the name being
(re)declared.

[Example:
    void h(unsigned Pc); // void h(unsigned int)
    void k(unsigned int Pc); // void k(unsigned int)
�end example] �end note]



So I the following is perfectly legal:

typedef foo int;

int f()
{
    foo foo;
    foo = 2;
}

Although it is EXTREMELY poor naming style.

-dr
0
ask242 (397)
9/11/2005 4:59:26 PM
[snip]
> So I the following is perfectly legal:
> 
> typedef foo int;

typedef int foo;

> 
> int f()
> {
>     foo foo;
>     foo = 2;
> }
> 
> Although it is EXTREMELY poor naming style.

but looks fun, doesnt it ? <:

> 
> -dr
0
Kyle
9/11/2005 10:42:18 PM
On Mon, 12 Sep 2005 00:42:18 +0200, Kyle <invalid@e.mail> wrote:

>[snip]
>> So I the following is perfectly legal:
>> 
>> typedef foo int;
>
>typedef int foo;

Why is "dyslexia" so hard to spell?

-dr
0
ask242 (397)
9/13/2005 4:56:01 AM
Reply: