开发者

g++ warning when using optional 'struct' keyword

If I write this program:

#include <iostream>

namespace foo {
    struct bar 开发者_高级运维{
        int x;
    };
}

int main (void) {
    struct foo::bar *a = new struct foo::bar;
    delete a;
    return 0;
}

and compile it with:

g++ main.cxx -Wall -Wextra

It gives me this warning:

main.cxx: In function ‘int main()’:
main.cxx:10:39: warning: declaration ‘struct foo::bar’ does not declare anything [enabled by default]

However, if I take out the struct keyword after the new keyword:

#include <iostream>

namespace foo {
    struct bar {
        int x;
    };
}

int main (void) {
    struct foo::bar *a = new foo::bar;
    delete a;
    return 0;
}

and compile it the same way, g++ outputs no warnings. Why does g++ output that warning if I use the struct keyword?


In C++, the struct keyword defines a type, and the new type no longer needs the struct keyword. This is one of the many differences between C and C++.


Examining the error:

main.cxx:10:39: warning: declaration ‘struct foo::bar’ does not declare anything [enabled by default]

g++ thinks you're declaring a new struct with the name foo::bar instead of allocating memory of type struct foo::bar. My guess would be because g++ assumes any usage of struct that doesn't declare an lvalue is for the purpose of declaring a type.


Just to post the minimal code that does and does not illustrate the problem:

namespace N {
struct A {};
}

struct B {};

int main() {
    struct N::A * a  = new struct N::A; // problem
    struct B * b  = new struct B;       // ok
}

Personally, I think this is a small GCC bug, but I am not wise in the myriad ways of namespaces.


Note:

   struct foo::bar *a = new struct foo::bar;
// ^^^^^^ (1)
                        //  ^^^^^^ (2)
  1. Not needed in C++
    • Putting struct here is a hangover from C and is no longer needed in C++
      As all the types are all in the same namespace.
      While in C structs had there own namespace separate from other types.
      It is allowed to retain backward compatibility with C.
  2. struct here looks like it is forward declaring something.

In C++ the above is written as:

   foo::bar* a = new foo::bar;

// or preferably

   foo::bar* a = new foo::bar(); // This makes a difference if you don't define
                                 // a default constructor.

From David (Below)

Important enough I think it needs to be in the answer rather than the comments:

namespace foo
{
    struct bar {};
    void bar() {}
}

int main()
{
    struct foo::bar* p = new struct foo::bar;
    // Needed here because the compiler can't tell the difference between
    // a struct and a function otherwise
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜