0

I recently saw this block at the beginning of a .h file.

#ifdef __cplusplus
  extern "C" {
  #include <cstddef>
  #include <cstdint>
#else
  #include <stddef.h>
  #include <stdint.h>
#endif /* __cplusplus */

Does wrapping a #include directive for a standard C++ header in extern "C" { ... actually do anything? Is it functionally different from:

#ifdef __cplusplus
  #include <cstddef>
  #include <cstdint>
  extern "C" {
#else
  #include <stddef.h>
  #include <stdint.h>
#endif /* __cplusplus */

I was under the impression that this makes no difference, but I'm seeing it so often I am becoming curious.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Zak
  • 12,213
  • 21
  • 59
  • 105
  • Where is the matching `}`? – Barmar Oct 10 '16 at 23:56
  • @JonathanLeffler Thank you for the help so far. – Zak Oct 11 '16 at 00:15
  • It is, in general, a tricky question (at least unless you know the answer) and I'm not sure of the answer — one reason why I didn't yet try to give one. The `` header defines some types and some macros; neither of those is affected by the presence or absence of `extern "C"`. The `` header likewise defines macros and types — it doesn't define any functions. That means, I think, that for those two headers specifically, it doesn't matter whether they're inside an `extern "C"` block or not. – Jonathan Leffler Oct 11 '16 at 00:17
  • The `` are generally dealing with code that might be implemented by functions with C linkage, so the chances are that including one of those inside an `extern "C" { … }` block is harmless. I'm not sure what's supposed to happen if you include general C++ headers that define C++ functions that should have C++ linkage. For templated code, and maybe namespace code, maybe it doesn't matter — I'm not sure what the standard has to say on the subject. For non-template code, I suspect you'd run into link-time errors — missing functions that were called with C linkage but not so defined. – Jonathan Leffler Oct 11 '16 at 00:21

1 Answers1

0

Based on the "If ...def" statement in that header file, the

"if" block : "if you use the particular header file in C++"

"else" block : "if you use the particular header file not in C++, could be C"

if you do not wrap the headers in "extern C" in the "if" block(which is meant for C++), the "C" linkage wont be maintained for the function names.

"C" do not have function over loading concept, but where as C++. So C++ compiler does some function name mangling for "extern C" functions.

Here is a very nice article. In C++ source, what is the effect of extern “C”? - in stack over flow.

For regular standard C libraries, the extern wrapper not required. Mostly it is taken care by standard C.

ex: something like below (yvals.h on windows).

  #define _C_LIB_DECL       extern "C" {    /* C has extern "C" linkage */
  #define _END_C_LIB_DECL   }
  #define _EXTERN_C         extern "C" {
  #define _END_EXTERN_C     }
Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34
  • Thank you for the response! Unfortunately, the link you referred to did not come through. Also, I want to make sure you are addressing whether or not the standard C libraries take this into account or not. I would be surprised if they don't, and that is why I wanted to ask the question. – Zak Oct 11 '16 at 16:30
  • Based on the code snippet you posted the answer is no. But here that particular code is in else block and the library developer did not want them for C++. Here is the link: http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c. And also not required for regular standard C libraries. – Pavan Chandaka Oct 11 '16 at 16:35
  • Would you mind update your answer with your comments? – Zak Oct 11 '16 at 16:52
  • Sure. Will do that. – Pavan Chandaka Oct 11 '16 at 17:04
  • Updated. please let me know if I need to add more – Pavan Chandaka Oct 11 '16 at 17:18
  • Note that system headers are allowed (indeed, required) to use names such as `_C_LIB_DECL` that start with an underscore and are followed by a capital letter or another underscore because those names are reserved for 'the system' to use. As a user, you should not create such names; you might use `C_LIB_DECL` instead. Check on the reserved names rules. – Jonathan Leffler Oct 11 '16 at 20:36