14

I would like to know where is better to put the

#ifdef __cplusplus
extern "C" {
#endif

in a C header file.

At the beginning or after all the other includes. why ?

1
  • 1
    I would say after the includes, because why would you put the includes inside that ifdef? Commented Apr 18, 2013 at 15:46

4 Answers 4

16

There are no strict rules on this, but note the following.

  1. The general principle is that each header file takes care of itself (and is self sufficient). So, by this principle, there would be no need to wrap the header files in a extern "C", because the header files would have an extern "C" in them (if they need one). So, in the current file, you would place it after the other includes.
  2. But if you do a have a whole bunch of headers, that you don't want to add an extern "C" to, and want to make available through a single include, by all means, go ahead and wrap them up in a file wide extern "C".

Just know that the idea behind extern "C" is that it makes the compiler generate C friendly linkage. Otherwise, code compiled with a C++ compiler looks for mangled names to link against in archives compiled with a C compiler, and can't find them.

Sign up to request clarification or add additional context in comments.

1 Comment

A third example: Actually, there are C libraries the author of which did not care about C++ and simply left out the extern "C" stuff. Would you now rather modify the foreign headers or include the unmodified headers wrapped by your own 'extern "C"'? I personally prefer the latter...
14

This construct is used to make your names available to a C linker (short explanation)

So obviously you want to use it around your stuff only.

Like this :

#ifndef MY_INCLUDE_H_ // include guard
#define MY_INCLUDE_H_

#include <...> // dependencies
#include "..."

#ifdef __cplusplus
extern “C” {
#endif

// ... your types, methods, variables

#ifdef __cplusplus
}
#endif

#endif // MY_INCLUDE_H_

2 Comments

@Aconcagua that should be taken care of in the included C headers, but as a last resort, yes. But in the .cpp file, not in the header.
Well, the thread is tagged 'C', too, so from this point of view, your example actually could have been a C header, too - unless you would have included some explicite C++ header or used some exclusive C++ code...
2
  • extern "C" affects linkage. When C++ functions compiled they have their names varies, that's why overloading in C++ is possible. So, function name gets modified based on the types and number of parameters, so two functions with the same names will have two different symbol names.

  • Code inside an extern "C" is still C++ code. There are limitations on what you can do in an extern "C" block, but they're all about linkage.

3 Comments

You might want to drop the term "c++ name mangling" in your otherwise clear answer
@Jaap Versteegh Why drop the term that is the term used to identify this kind of behavior? If someone wants to read more about what is happening and why, this is the term they should use to search for more information.
@hobb I meant to say "drop in" as in "add". Name mangling was not mentioned in the answer and like you say, this is the name for this behaviour.
1

extern "C" affects the way that code is compiled. Headers that are designed to be compiled both as C and as C++ will manage extern "C" themselves. You should never wrap a #include directive in an extern "C" block: if the header involved was designed to be compiled both ways your directive is redundant, and if it wasn't designed to be used both ways it's an error.

1 Comment

What did you mean by "are designed" and "wasn't design"?

Your Answer

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.