How does an extern “C” declaration work?

2019-01-08 13:44发布

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 other than "it interfaces C and C++"? How does this affect the bindings that take place in the program as well?

标签: c++ c extern-c
9条回答
倾城 Initia
2楼-- · 2019-01-08 14:35

extern C affects name mangling by the C++ compiler. Its a way of getting the C++ compiler to not mangle names, or rather to mangle them in the same way that a C compiler would. This is the way it interfaces C and C++.

As an example:

extern "C" void foo(int i);

will allow the function to be implemented in a C module, but allow it to be called from a C++ module.

The trouble comes when trying to get a C module to call a C++ function (obviously C can't use C++ classes) defined in a C++ module. The C compiler doesn't like extern "C".

So you need to use this:

#ifdef __cplusplus
extern "C" {
#endif

void foo(int i);

#ifdef __cplusplus
}
#endif

Now when this appears in a header file, both the C and C++ compilers will be happy with the declaration and it could now be defined in either a C or C++ module, and can be called by both C and C++ code.

查看更多
ゆ 、 Hurt°
3楼-- · 2019-01-08 14:37

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.

查看更多
女痞
4楼-- · 2019-01-08 14:42

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).

查看更多
登录 后发表回答