9

Following code doesn't compile g++ 4.8.1

struct Layers
{
    typedef struct Widgets { } Widgets;

    virtual void fun(void) 
    {
        struct Widgets w;
    }

    Widgets w, x, y, z ;
};

However, if I just use Widgets w, x, y ; //Remove variable z it compiles !

Why is this happening ? What am I missing here ?

P0W
  • 46,614
  • 9
  • 72
  • 119

2 Answers2

7

That's because you typedef'd the structure Widgets, check the error out:

error: using typedef-name 'Layers::Widgets' after 'struct'

So, the workaround is to remove the struct in the function. Summing it up to:

struct Layers
{
    typedef struct Widgets { } Widgets;

    virtual void fun(void) 
    {
        Widgets w;
    }

    Widgets w, x, y, z ;
};

int main() { }

Read more about this here: Difference between 'struct' and 'typedef struct' in C++?

Community
  • 1
  • 1
  • 6
    This does not explain why removing `,z' makes the code compile – rano Apr 24 '14 at 05:46
  • 1
    The weirdness is that removal `, z` fix things :) Looks like a language parser /feature/ (somewhat similar to a bug) – user3159253 Apr 24 '14 at 05:46
  • I'm not quite sure why removing `z` would make it work. Didn't take into account while posting this answer. –  Apr 24 '14 at 05:47
  • @user3159253 it's mostly a bug, yep. Should try with another compiler to make sure –  Apr 24 '14 at 05:49
  • @P0W: I don't see the behavior that removing `z` removes the error. Are you saying that the error is on the `struct Widgets w;` declaration in `fun()` and that removing `z` from the latter declaration makes it so there's no longer an error om the declaration in `fun()`? Like I said - I can't repro that, and it doesn't make sense to boot. – Michael Burr Apr 24 '14 at 05:51
  • @MichaelBurr It turned out to be a GCC(4.8.1) parser bug. Are you trying with another version? –  Apr 24 '14 at 05:52
  • gcc 4.2.1 seems affected as well – rano Apr 24 '14 at 05:53
  • I'm trying on `gcc (tdm64-2) 4.8.1` (a MinGW build running on Windows, but I'd think that the parser should be the same across all 4.8.1 GCC versions). – Michael Burr Apr 24 '14 at 05:54
  • Well - I take all that back. I had pasted the snippet into a little 'hello world' program and wasn't able to repro the behavior. When I tried compiling the snippet with nothing else, I got the repro. Strange bug. – Michael Burr Apr 24 '14 at 05:56
  • @MichaelBurr See OP's answer, seems like it was fixed in 4.9.0 –  Apr 24 '14 at 05:57
7

Its a bug in GCC

Ref: -Bug 46206 - using typedef-name error with typedef name hiding struct name

G++ rejects the following code:

class Foo
{
    bool a, b, c, d;
    typedef struct Bar { } Bar;
    virtual void foo(void) {
        struct Bar bar;
    }
};    
example.cc: In member function ‘virtual void Foo::foo()’:
example.cc:6: error: using typedef-name ‘Foo::Bar’ after ‘struct’
example.cc:4: error: ‘Foo::Bar’ has a previous declaration here
example.cc:6: error: invalid type in declaration before ‘;’ token

but accepts many similar examples, including:

class Foo
{
    bool a, b, c;
    typedef struct Bar { } Bar;
    virtual void foo(void) {
        struct Bar bar;
    }
};

This behaviour is reproducible on x86_64-redhat-linux (4.1.2 and 4.4.0) and i386-pc-solaris2.11 (4.2.4, 4.3.4 and 4.5.1)

I'm uncertain if this is strictly legal or not per the standard, but it doesn't seem to make sense to accept one of these cases but not the other...

This appears to be fixed in latest GCC 4.9.0

gnat
  • 6,213
  • 108
  • 53
  • 73
P0W
  • 46,614
  • 9
  • 72
  • 119
  • 2
    lol, there's an example just like yours. This could be a good way to farm reputation : D – rano Apr 24 '14 at 05:58
  • @rano Seriously I still don't know the real problem, just happen to search similar bug on bugzilla – P0W Apr 24 '14 at 05:59
  • I'm not sure if it's fixed in 4.9.0 (I don't have an install of that yet). The last comment by Paolo Carlini was that he reverted the patch. – Michael Burr Apr 24 '14 at 06:04
  • @MichaelBurr: Even more strange he claims it only worked on linux. That makes me think that gcc is internally invoking UB somewhere... – PlasmaHH Apr 24 '14 at 09:12