How does an extern “C” declaration work?

后端 未结 9 737
礼貌的吻别
礼貌的吻别 2020-12-02 14:33

I\'m taking a programming languages course and we\'re talking about the extern \"C\" declaration.

How does this declaration work at a deeper level othe

相关标签:
9条回答
  • 2020-12-02 15:07

    extern "C" denotes that the enclosed code uses C-style linking and name mangling. C++ uses a more complex name mangling format. Here's an example:

    http://en.wikipedia.org/wiki/Name_mangling

    int example(int alpha, char beta);
    

    in C: _example

    in C++: __Z7exampleic

    Update: As GManNickG notes in the comments, the pattern of name mangling is compiler dependent.

    0 讨论(0)
  • 2020-12-02 15:09

    extern "C" is used to ensure that the symbols following are not mangled (decorated).


    Example:

    Let's say we have the following code in a file called test.cpp:

    extern "C" {
      int foo() {
        return 1;
      }
    }
    
    int bar() {
      return 1;
    }
    

    If you run gcc -c test.cpp -o test.o

    Take a look at the symbols names:

    00000010 T _Z3barv

    00000000 T foo

    foo() keeps its name.

    0 讨论(0)
  • 2020-12-02 15:10

    It should be noted that extern "C" also modifies the types of functions. It does not only modify things on lower levels:

    extern "C" typedef void (*function_ptr_t)();
    
    void foo();
    
    int main() { function_ptr_t fptr = &foo; } // error!
    

    The type of &foo does not equal the type that the typedef designates (although the code is accepted by some, but not all compilers).

    0 讨论(0)
  • 2020-12-02 15:11

    Let's look at a typical function that can compile in both C and C++:

    int Add (int a, int b)
    {
        return a+b;
    }
    

    Now in C the function is called "_Add" internally. Whereas the C++ function is called something completely different internally using a system called name-mangling. Its basically a way to name a function so that the same function with different parameters has a different internal name.

    So if Add() is defined in add.c, and you have the prototype in add.h you will get a problem if you try to include add.h in a C++ file. Because the C++ code is looking for a function with a name different to the one in add.c you will get a linker error. To get around that problem you must include add.c by this method:

    extern "C"
    {
    #include "add.h"
    }
    

    Now the C++ code will link with _Add instead of the C++ name mangled version.

    That's one of the uses of the expression. Bottom line, if you need to compile code that is strictly C in a C++ program (via an include statement or some other means) you need to wrap it with a extern "C" { ... } declaration.

    0 讨论(0)
  • 2020-12-02 15:16

    In C++ the name/symbol of the functions are actually renamed to something else such that different classes/namespaces can have functions of same signatures. In C, the functions are all globally defined and no such customized renaming process is needed.

    To make C++ and C talk with each other, "extern C" instructs the compiler not to use the C convention.

    0 讨论(0)
  • 2020-12-02 15:16

    extern "C", is a keyword to declare a function with C bindings, because C compiler and C++ compiler will translate source into different form in object file:

    For example, a code snippet is as follows:

    int _cdecl func1(void) {return 0}
    int _stdcall func2(int) {return 0}
    int _fastcall func3(void) {return 1}
    

    32-bit C compilers will translate the code in the form as follows:

    _func1
    _func2@4
    @func3@4
    

    in the cdecl, func1 will translate as '_name'

    in the stdcall, func2 will translate as '_name@X'

    in the fastcall, func2 will translate as '@name@X'

    'X' means the how many bytes of the parameters in parameter list.

    64-bit convention on Windows has no leading underscore

    In C++, classes, templates, namespaces and operator overloading are introduced, since it is not allowed two functions with the same name, C++ compiler provide the type information in the symbol name,

    for example, a code snippet is as follows:

    int func(void) {return 1;}
    int func(int) {return 0;}
    int func_call(void) {int m=func(), n=func(0);}
    

    C++ compiler will translate the code as follows:

    int func_v(void) {return 1;}
    int func_i(int) {return 0;}
    int func_call(void) {int m=_func_v(), n=_func_i(0);}
    

    '_v' and '_i' are type information of 'void' and 'int'

    0 讨论(0)
提交回复
热议问题