简体   繁体   中英

Why can't I complete the type with the typedef?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM