Given an incomplete type in translation unit A:
struct Incomplete;
Incomplete* create_incomplete();
void destroy_incomplete(Incomplete*);
why can't I use it in another translation unit, by using typedef
?
For example in translation unit B:
struct Unrelated
{
int x;
int y;
};
typedef Unrelated Incomplete;
Incomplete* create_incomplete()
{
return new Incomplete();
}
void destroy_incomplete(Incomplete* arg)
{
delete arg;
}
Incomplete
is a type, introduced by your declaration and you cannot have a typedef using the same name, refering to another type.
Your struct Incomplete;
is a forward class declaration which inserts a class-name into the global scope (and introduces a new, yet incomplete type).
§9/2
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen.
§9.1/2
A declaration consisting solely of class-key identifier; is either a redeclaration of the name in the current scope or a forward declaration of the identifier as a class name.
In order to use that name where a complete type is required, it must be defined.
§3.2/4
Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the class type to be complete.
A class ist defined using the class-specifier.
§9/2
A class is considered defined after the closing brace of its class-specifier has been seen even though its member functions are in general not yet defined.
Your typedef is a declaration and does not define the class.
§7.1.3/1
Declarations containing the decl-specifier typedef declare identifiers that can be used later for naming fundamental (3.9.1) or compound (3.9.2) types.
§3.1/2
A declaration is a definition unless [...] it is a typedef declaration [...].
Whereas declarations in the same scope / declarative region are required to refer to the same entity.
§3.3.1/4
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name
- they shall all refer to the same entity, or all refer to functions and function templates; [ ... ]
Your typedef declares Incomplete
to refer to Unrelated
whereas struct Incomplete;
declares a type Incomplete
.
§7.1.3/6
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.
C++11
You can't complete something that is declared in a different translation unit . Either you #include
your first file in the second one and in this case you have everything happening in a single translation unit, or, if you don't #include
it, you just have a typedef
and no incomplete types in unit B and an incomplete type (which you don't ever complete because you don't have to) in unit A.
And you can't complete a class with a typedef
in a single unit, because:
3.9.5. A class that has been declared but not defined , or an array of unknown size or of incomplete element type, is an incompletely-defined object type. Incompletely-defined object types and the void types are incomplete types .
3.9.2. A declaration is a definition unless <…> it is a
typedef
declaration, <…>.
( N3337 ; some emphases add by me.)
So, you can't complete a class type with a typedef
because a class type can be completed only by a definition and typedef
declaration is not a definition.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.