[C++] language linkage

1. translation units

P17 - § 2.1

The text of the program is kept in units called source files in this International Standard. A source file together with all the headers and source files included via the preprocessing directive #include, less any source lines skipped by any of the conditional inclusion preprocessing directives, is called a translation unit.

2. program

P59 - § 3.5

A program consists of one or more translation units linked together. A translation unit consists of a sequence of declarations.

translation-unit:
    declaration-seq[opt]

3. linkage

P59 - § 3.5

A name is said to have linkage when it might denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope:

(1) When a name has external linkage , the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.

(2) When a name has internal linkage , the entity it denotes can be referred to by names from other scopes in the same translation unit.

(3) When a name has no linkage , the entity it denotes cannot be referred to by names from other scopes.

4. language linkage

P174 - § 7.5

All function types, function names with external linkage, and variable names with external linkage have a language linkage.

The default language linkage of all function types, function names, and variable names is C++ language linkage. Two function types with different language linkages are distinct types even if they are otherwise identical.

Linkage between C++ and non-C++ code fragments can be achieved using a linkage-specification:

linkage-specification:
    extern string-literal { declaration-seq[opt] }
    extern string-literal declaration

The string-literal indicates the required language linkage. This International Standard specifies the semantics for the string-literals "C" and "C++". Use of a string-literal other than "C" or "C++" is conditionally-supported, with implementation-defined semantics.

Every implementation shall provide for linkage to functions written in the C programming language, "C", and linkage to C++ functions, "C++".

complex sqrt(complex);    // C++ linkage by default
extern "C" { 
    double sqrt(double);  // C linkage
}

5. nested linkage specification

P174 - § 7.5

Linkage specifications nest. When linkage specifications nest, the innermost one determines the language linkage. A linkage specification does not establish a scope. A linkage-specification shall occur only in namespace scope. In a linkage-specification, the specified language linkage applies to the function types of all function declarators, function names with external linkage, and variable names with external linkage declared within the linkage-specification.

// the name f1 and its function type have C language linkage; 
// pf is a pointer to a C function
extern "C" void f1(void(*pf)(int));

extern "C" typedef void FUNC();

// the name f2 has C++ language linkage and
// the function’s type has C language linkage
FUNC f2;

// the name of function f3 and the function’s type 
// have C language linkage
extern "C" FUNC f3;

// the name of the variable pf2 has C++ linkage and 
// the type of pf2 is pointer to C++ function that 
// takes one parameter of type pointer to C function
void (*pf2)(FUNC*);

extern "C" { 

    // the name of the function f4 has internal linkage (not C language linkage) 
    // and the function’s type has C language linkage.
    static void f4();
}

extern "C" void f5() { 

    // OK: Name linkage (internal) and function type linkage (C language linkage) 
    // gotten from previous declaration.
    extern void f4();
}

// OK: Name linkage (internal) and function type linkage (C language linkage) 
// gotten from previous declaration.
extern void f4();

void f6() {

    // OK: Name linkage (internal) and function type linkage (C language linkage) 
    // gotten from previous declaration.
    extern void f4();
}

6. ignore C language linkage

P175 - § 7.5

A C language linkage is ignored in determining the language linkage of the names of class members and the function type of class member functions.

extern "C" typedef void FUNC_c(); 
class C {

    // the name of the function mf1 and the member function’s type have C++ language linkage; 
    // the parameter has type pointer to C function
    void mf1(FUNC_c*);

    // the name of the function mf2 and the member function’s type have C++ language linkage
    FUNC_c mf2;

    // the name of the data member q has C++ language linkage and
    // the data member’s type is pointer to C function
    static FUNC_c* q;
};

extern "C" { 
    class X { 

        // the name of the function mf and the member function’s type have C++ language linkage
        void mf();

        // the name of the function mf2 has C++ language linkage; 
        // the parameter has type pointer to C function
        void mf2(void(*)());
    };
}

7. name clash

P175 - § 7.5

If two declarations declare functions with the same name and parameter-type-list to be members of the same namespace or declare objects with the same name to be members of the same namespace and the declarations give the names different language linkages, the program is ill-formed; no diagnostic is required if the declarations appear in different translation units. Except for functions with C++ linkage, a function declaration without a linkage specification shall not precede the first linkage specification for that function.

A function can be declared without a linkage specification after an explicit linkage specification has been seen; the linkage explicitly specified in the earlier declaration is not affected by such a function declaration.

At most one function with a particular name can have C language linkage. Two declarations for a function with C language linkage with the same function name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same function. Two declarations for a variable with C language linkage with the same name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same variable.

An entity with C language linkage shall not be declared with the same name as an entity in global scope, unless both declarations denote the same entity; no diagnostic is required if the declarations appear in different translation units. A variable with C language linkage shall not be declared with the same name as a function with C language linkage (ignoring the namespace names that qualify the respective names); no diagnostic is required if the declarations appear in different translation units.

int x; 

namespace A { 
    extern "C" int f(); 
    extern "C" int g() { 
        return 1; 
    } 
    extern "C" int h(); 

    // ill-formed: same name as global-space object x
    extern "C" int x(); 
}

namespace B {

    // A::f and B::f refer to the same function
    extern "C" int f(); 

    // ill-formed, the function g with C language linkage has two definitions
    extern "C" int g() { 
        return 1; 
    }
}

// definition for the function f with C language linkage
int A::f() { 
    return 98; 
} 

// definition for the function h with C language linkage
// A::h and ::h refer to the same function
extern "C" int h() { 
    return 97; 
}

8. declaration & definition

P176 - § 7.5

A declaration directly contained in a linkage-specification is treated as if it contains the extern specifier for the purpose of determining the linkage of the declared name and whether it is a definition. Such a declaration shall not specify a storage class.

extern "C" double f(); 
static double f();           // error
extern "C" int i;            // declaration
extern "C" {     
    int i;                   // definition
} 
extern "C" static void g();  // error

9. function pointer

P176 - § 7.5

Because the language linkage is part of a function type, when a pointer to C function (for example) is dereferenced, the function to which it refers is considered a C function.

10. other languages

P176 - § 7.5

Linkage from C++ to objects defined in other languages and to objects defined in C++ from other languages is implementation-defined and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved.


参考

github: cplusplus/draft
The C++ Standards Committee
ISO/IEC 14882:2011

你可能感兴趣的:([C++] language linkage)