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)
- 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 samenamespace
.
While in C structs had there own namespace separate from other types.
It is allowed to retain backward compatibility with C.
- Putting struct here is a hangover from C and is no longer needed in C++
- 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
}
精彩评论