Question

This is my second investigation about structure declaration in C++. (The first is here) But now I came across this post. Specifically I am not sure why this is perfectly fine in C but not in C++.

typedef struct{
    int one;
    int two;
}myStruct;

struct myStruct; //forward declaration fails

void blah(myStruct* pStruct);

The code above compiles fine on my Ubuntu box with GCC. I reason that it is because the first myStruct lives in the normal namespace where function, variable names live. The second myStruct lives in the Tag namespace. When compiler sees myStruct* in the function prototype, it searches in both namespaces and found myStruct in the normal namspace and that name happen to be a typedef name, so it can be a valid type specifier. The second myStruct can be defined later as whatever the programmer wants to be. There won't be any confusion/collision with the first unnamed myStruct since the programmer has to use struct myStruct to refer to the second one.

But in C++, according to the discussion found in the linked question, my understanding is that the first typedef myStruct lives in the normal namespace as usual. The second myStruct also lives in the normal namespace(no specific tag namespace in C++?) but can be overshadowed by other identifiers. So my question is why wouldn't the first myStruct which is in the same namespace as the second myStruct shadow the second myStruct?

In a more general sense, other than explicit namespaces introduced by the programmer using the namespace facility provided by the C++ language, are there any pre-defined namespaces disambiguating the use of identifiers (including tags, labels, typedef names, object/functino identifiers) like in C? (C has 4 namespaces pre-defined found in my first investigation). Can I find these in the C++ standard stating where these names belong?

EDIT: It seems I didn't ask the question clear enough. All I want to know is

1) Which namespaces (if there are such defined in the language) do Lables, typedef names, tag names of struct/union/enum, normal function, normal variable/object name belong? (If I missed any other kinds of name, please add.)

2) Why can normal function name, normal variable name shadow tag names, while tag names can NOT.

3) If there is any clauses in C++ that specify the name spaces like in C (Section 6.2.1)

Était-ce utile?

La solution

In C++, you cannot use struct myStruct to refer to a tagless structure which has been typedefed. And you cannot define a different struct myStruct, because the name collides with the typedef name.

If you add the tag, then both struct myStruct and myStruct alone will refer to the type, in both C and C++:

typedef struct myStruct {
    int one;
    int two;
} myStruct;

Here there is no collision in C++ because the name resolves to just one type, and this is specifically allowed by a special rule. C++ Standard section 7.1.3 includes the following rules:

In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers.

If a typedef specifier is used to redefine in a given scope an entity that can be referenced using an elaborated-type-specifier, the entity can continue to be referenced by an elaborated-type-specifier or as an enumeration or class name in an enumeration or class definition respectively.

In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type.

Similarly, in a given scope, a class or enumeration shall not be declared with the same name as a typedef-name that is declared in that scope and refers to a type other than the class or enumeration itself.

[ Note: A typedef-name that names a class type, or a cv-qualified version thereof, is also a class-name (9.1). If a typedef-name is used to identify the subject of an elaborated-type-specifier (7.1.6.3), a class definition (Clause 9), a constructor declaration (12.1), or a destructor declaration (12.4), the program is ill-formed. — end note ]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top