James said:
Are you sure about union? I don't have my copy of the standard
(or any draft, for that matter) handy to check, but I seem to
remember that unions got special handling in this regard. (A
union is a class... except when it isn't.)
I think you have the IsClass and IsClassType concepts of c++0x in mind,
which made a difference between union and struct/class. But in general,
unions indeed are classes (so for instance, it's indeed possible to have
"union templates" without anything explicitly stating that in the Standard).
What is not allowed is "enum A &mya".
IIRC, it's more subtle than that. The second names a class in
function prototype scope. And I don't see where you're going to
be able to define a class in function prototype scope, so the
second effectively names a class which can't be defined.
That's only the case in C. In C++ such a class will be a member of the
enclosing namespace, as said by 3.3.2/6. Granted, it just says that the
class-name is declared in the enclosing namespace. But its intent seems that
the class is also a member of that namespace (so, scope of a name determines
identity of the entity referred to, here).
In C you will only be able to define such a type by having a struct
declaration for the new type placed into another TU, because the first
declaration and the second declaration of the tag identifier will refer to
different entities if you try to define the type in the same TU. If you
define it in another TU and then in that other TU define the function, then
both functions across the TU are of compatible types (not the same - but
that's not necessary) and behavior is well defined. Scopes are not used for
randomly determining identity of an entitiy in C (but merely linkage does -
and identifiers of types have no linkage).
This code works on comeau and GCC (getting back to C++ again), and indeed
shows that the class is a member of the enclosing namespace, rather than a
local class or something else:
void f(class X);
class X { };
void f(X x) { }
int main() {
&f; // f is not an overloaded function
}
(From memory. And this is really the sort of question where I
miss not having my copy of the standard handy, because name
lookup isn't always that trivial.)
Yeah, name lookup and especially rules about declarative regions and scopes
and identity are confusing in my opinion
Except in header files which have to be used in both C and C++
(in which case, of course, it's "struct A*", and not "class
A&").
Tho i believe most people will go the easy way and do "struct A;" at the
start of those function declarations, rather than sprinkling the code with
those in-line forward declarations