10

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?

2
  • Interestingly neither clang++ nor comeau complain about the syntax, and a cursory look into the standard (C++03) didn't help understand the problem either. Commented Jun 1, 2011 at 21:05
  • 1
    As it is only a warning, I hesitate to say bug - but a GCC bug? The code looks OK to me. Also, it is namespace associated - doing the same thing without a namespace does not produce a warning. Commented Jun 1, 2011 at 21:07

4 Answers 4

5

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++.

Sign up to request clarification or add additional context in comments.

4 Comments

This explain why the latter code works, but not why the first code produced a warning.
I understand that it's unnecessary to use the keyword in C++; I say that it's optional in the thread title. Thanks for responding though.
Is it optional? What does the standard have to say about that?
According to MSDN, the struct keyword is "is unnecessary once the type has been defined." This is what I meant, so I apologize if I was being ambiguous.
3

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.

4 Comments

I understand what you say, but if the compiler is considering that a new type is being declared, then it should bail out with an error, not produce a simple warning, as the standard explicitly states that you cannot declare new types in the new expression
@Adetque It is a good idea to wait at least 24 hours before accepting an answer, so others can have chance to reply. In this case, I think the answer you have accepted is wrong.
@David : Maybe we should just be happy that g++ is punishing users who treat C++ as C-with-classes. ;-P
@Neil Butterworth: Ok, I will be sure to do that. @ildjarn: I try to avoid treating it like that. It's just a habit I have from C.
2

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.

Comments

1

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
}

1 Comment

1. Not needed in C++, or needed, depending on the rest of the code: namespace foo { struct bar {}; void bar() {} } int main() { struct foo:bar* p = new struct foo::bar; }. In that particular convoluted example, the use of struct is needed in C++ to tell the compiler to search for bar in namespace foo but only in the set of user defined types --and avoid other types of identifiers, like functions or variables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.