Linkage

Identifier names can refer to different identifiers in different scopes. An identifier declared in different scopes or in the same scope more than once can be made to refer to the same identifier or function by a process called “linkage.” Linkage determines the portions of the program in which an identifier can be referenced (its “visibility”). There are three kinds of linkage: internal, external, and none.

Internal Linkage

If the declaration of a file-scope identifier for an object or a function contains the storage-class-specifier static, the identifier has internal linkage. Otherwise, the identifier has external linkage. See topic for a discussion of the storage-class-specifier nonterminal.

Within one translation unit, each instance of an identifier with internal linkage denotes the same identifier or function. Internally linked identifiers are unique to a translation unit.

External Linkage

If the first declaration at file-scope level for an identifier does not use the static storage-class specifier, the object has external linkage.

If the declaration of an identifier for a function has no storage-class-specifier, its linkage is determined exactly as if it were declared with the storage-class-specifier extern. If the declaration of an identifier for an object has file scope and no storage-class-specifier, its linkage is external.

An identifier's name with external linkage designates the same function or data object as does any other declaration for the same name with external linkage. The two declarations can be in the same translation unit or in different translation units. If the object or function also has global lifetime, the object or function is shared by the entire program.

No Linkage

If a declaration for an identifier within a block does not include the extern storage-class specifier, the identifier has no linkage and is unique to the function.

The following identifiers have no linkage:

An identifier declared to be anything other than an object or a function

An identifier declared to be a function parameter

A block-scope identifier for an object declared without storage-class-specifier extern

If an identifier has no linkage, declaring the same name again (in a declarator or type specifier) in the same scope level generates a symbol redefinition error.