10

Is there a difference whether I use the extern "C" specifier for the entire header, or specify extern for every function?

As far as I know, there is none, since only functions and variables can be linked externally, so when I use the extern specifier before every function prototype and extern variable, I have no need to use the global extern "C" declaration!?

Example A:

#ifdef __cplusplus
extern "C" {
#endif

void whatever(void);

#endif

Example B:

extern void whatever(void);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    `extern "C"` is really nothing to do with `extern` on its own . just re-use a keyword for two different purposes instead of making new keywords – M.M May 18 '17 at 22:18
  • A tiny lamp to illuminate https://asciinema.org/a/oln2xgaO2TUM95DDEAJMBfg0e – daparic Mar 19 '20 at 18:42

2 Answers2

16

The presence of extern "C" in a C++ file allows to call the particular C++ function from a C client caller code.

What is the difference?

A long, long time ago C-compilers generated code and addressed functions by name only. It didn't consider parameters.

When overloaded functions were introduced in C++, extern "C" was required to specify the same name for different functions. For example void f() and void f(int) are two different functions in C++.

The C++ compiler accomplished this via name-mangling. It adds some info to the function name related to the functions parameters.

extern "C" is a command to the compiler to "refer to the older style naming convention - without mangling".

daparic
  • 3,794
  • 2
  • 36
  • 38
Dmitry Poroh
  • 3,705
  • 20
  • 34
  • 1
    Didn't you mean the opposite here? *extern "C" means to call C-library function from C++ code.* So shouldn't it be: *call C++ function from C code*? – Mohammed Noureldin Jun 14 '19 at 07:52
  • 1
    This works in both directions. You can write C-linkable functions in C++ using extern "C". But I think that calling C++-code from C is not as common as oposite one. – Dmitry Poroh Jun 14 '19 at 10:56
  • Here is a tiny supplement https://asciinema.org/a/Zk7HJlf8yuerv6VZ6pkmqyfEa – daparic Mar 19 '20 at 18:53
10

There is a difference between those two things.

The first says "the functions in here should be compiled so as to be callable from C". C++ allows multiple functions to have the same name as long as they take different arguments. C does not. To achieve that, C++ includes argument type information in the compiled name of its functions. As a result a C compiler will not be able to find the functions. If you add an extern "C" then you instead get C behaviour, but you gain the ability to call those functions from C.

The latter says "this function exists in another compilation unit". Which means that a compiler should trust that the function with that signature exists but not worry about being unable to see it. It'll be there when you link, you promise. Declarations (contrasting with definitions) are extern by default since at least C99.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • 1
    Does `extern "C"` only affect name mangling or does it also guarantee the use of the `cdecl` calling convention? – cbr May 18 '17 at 22:03