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
<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.
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
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
[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 |
![]() |
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