5

Consider the following:

#include <type_traits>

struct MyType {
    int val;
    MyType(void) = default;
    MyType(int v) : val(v) {}
};
static_assert(std::is_standard_layout<MyType>::value,"Implementation error!");
static_assert(std::is_trivial<MyType>::value,"Implementation error!");
static_assert(std::is_pod<MyType>::value,"Implementation error!");

struct Wrapper {
    struct {
        MyType t;
    };
};

MSVC, Clang, and Intel C++ all compile it fine. But g++4.9 foo.cpp -std=c++11 tells me:

14 : error: member 'MyType Wrapper::<anonymous struct>::t' with constructor not allowed in anonymous aggregate
MyType t;
^
Compilation failed

Notice that the static_asserts ensure that MyType is a standard layout type, a trivial type, and moreover is actually POD (note that after C++11, PODs are allowed to have constructors).


I couldn't find anything authoritative about what types are allowed inside anonymous structures. What I did find (mostly here on SO) suggest that being a POD type is sufficient. Apparently, it is not.

My question: If being a POD type is actually insufficient for being in an anonymous structure, what is sufficient? Or perhaps, since GCC is differing from all other compilers, is this a problem with GCC?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
geometrian
  • 14,775
  • 10
  • 56
  • 132
  • 2
    [Doesn't compile in Clang](http://melpon.org/wandbox/permlink/EymdTe46Ss7Sn1xA); isn't well-formed C++. – Kerrek SB Aug 22 '16 at 00:01
  • @KerrekSB: It [does compile](http://melpon.org/wandbox/permlink/4S88COP93nH4zyeV) when you change the anonymous struct into a regular unnamed one. Granted, I'm not sure if the OP [understands the difference.](http://stackoverflow.com/q/14248044/734069) While I think his question is mainly about the behavior of complex types within unnamed structs, the OP needs to clarify that before we can proceed. – Nicol Bolas Aug 22 '16 at 00:08
  • @NicolBolas I understand now better the terminology. However, the question is still under-which-conditions-GCC-accepts-the-code. Evidently, it's not required to--since only unnamed structs are standard so far--but I'm surprised being a POD type is insufficient. – geometrian Aug 22 '16 at 00:20
  • @imallett: "*However, the question is still under-which-conditions-GCC-accepts-the-code.*" Accepts the code that isn't legal C++? Or accepts the code that *might be* legal C++ depending on whether `MyType` can be placed in an unnamed struct? Which "the code" are you talking about? Also, if you're asking about what compilers do, rather than what the language says should happen, then you shouldn't use the "language-lawyer" tag. – Nicol Bolas Aug 22 '16 at 00:35

1 Answers1

5

As far as standards are concerned, anonymous structs are a C feature. They are not allowed by any C++ standard.

I could not find detailed gcc documentation about their extension to provide the feature in C++. What little I found is here, but that page appears to only describe the extension for C (prior to C11, this feature was not standard).

My question: If being a POD type is actually insufficient for being in an anonymous structure,

It indeed appears to be insufficient. The error message explains quite clearly that having a (non-trivial) constructor disqualifies a class from being an anonymous aggregate (structure). A POD would guarantee this only prior to C++11.

Since there appears to be little documentation for the extension, and since anonymous structs are a C feature, I'm tempted to guess that any such aggregate must not use C++ features. I believe that pre-C++11 definition of a POD satisfies such requirement.

A quick test appears to agree with my hypothesis. If you remove the constructor, the program compiles with the extension enabled. If you name the struct member (promoting the type to be unnamed), the program becomes well formed standard C++, and also compiles.

Or perhaps, since GCC is differing from all other compilers, is this a problem with GCC?

Since that's the way they implemented it, it quite possibly isn't a problem with them. It could be a problem to someone who wishes to compile without modification, a non-standard program written for another compiler. This is a problem with non-standard language features in general.

eerorika
  • 232,697
  • 12
  • 197
  • 326