Skip to main content
  1. About
  2. For Teams
Asked
Viewed 8k times
10

Why shouldn’t extern "C" be specified for a function that needs to be defined as a C function? What effect would that have on the compiler when compiling the file as a C source?

If there is no effect on the C compiler, can’t we just define a function in a header file as below by removing the #ifdef __cplusplus check?

extern "C" {
    int MyFunc();
}

An answer to another question says that the #ifdef is needed, but I don’t understand why:

Regarding #2: __cplusplus will be defined for any compilation unit that is being run through the C++ compiler. Generally, that means .cpp files and any files being included by that .cpp file. The same .h (or .hh or .hpp or what-have-you) could be interpreted as C or C++ at different times, if different compilation units include them. If you want the prototypes in the .h file to refer to C symbol names, then they must have extern "C" when being interpreted as C++, and they should not have extern "C" when being interpreted as C -- hence the #ifdef __cplusplus checking.

2 Answers 2

22

The construct extern "C" is a C++ construct and is not recognized by a C compiler. Typically, it will issue a syntax error message.

A common trick is to define a macro, for example EXTERN_C, that would expand to different thing depending on if you compile using C or C++. For example:

In a common header file:

#ifdef __cplusplus
#define EXTERN_C extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_END
#endif

In other files:

EXTERN_C
int MyFunc(void);
EXTERN_C_END
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I didn't knew it was a C++ construct.
2

If you compile a source file as C, it will not recognize extern "C", and would usually result in a compilation error.

If you compile a source file as C++, it will recognize extern "C", and the correct names will be linked.

Therefore, you can only use it reliably to specify C symbol names for files you compile as C++.

If you compile sources as C and C++, or your interfaces are intended for C and C++ clients, you would need to specify this one way or another in order for your clients to get the correct symbols when linking (and so on).

Related: You are allowed to write extern "C++" - for C++ translations.

Comments

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.