http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53184
--- Comment #4 from Jason Merrill <jason at gcc dot gnu.org> 2012-05-02 17:23:09 UTC --- (In reply to comment #3) > Because then the anonymous class has the name "Foo" for linkage purposes, and > has external linkage. When Foo referes to the const or volatile qualified > form > of the class, the anonymous class itself has no name and so no linkage, only > the cv-qualified form has a name for linkage purposes. > > I'm not sure if that behaviour is correct though, let's ask Jason Yes, that's right. 7.1.3: If the typedef declaration defines an unnamed class (or enum), the first typedef-name declared by the declaration to be that class type (or enum type) is used to denote the class type (or enum type) for linkage purposes only (3.5). typedef struct { } *ps, S; // S is the class name for linkage purposes Adding volatile means that Foo doesn't name the class, it names the volatile variant of the class, so it isn't the class's name for linkage purposes, so the class has no linkage. The warning complains about using a type with no linkage as a member type in a header file, since including that header in multiple source files would be an ODR violation as the type Foo is different in each translation unit.