Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the specified behavior of including a standard C header, in C++ code, inside a linkage-specification (extern "C", extern "C++")?

Typically one includes standard library headers in C++ in the global namespace, outside of any externs, like so:

#include <stdint.h>

int main() { }

But what's specified to happen if you include a standard library header inside one? For example:

extern "C" {
#include <stdint.h>
}
int main() { }

or

extern "C++" {
#include <stdint.h>
}
int main() { }

Is it specified what should happen in either case, or is it implementation-defined or even undefined?

C++11 17.6.2.3p1 says that C++ standard library headers put stuff in extern "C++", but my tentative reading is that this doesn't apply to C headers like <stdint.h>. C++11 17.6.2.2p3 says headers can only be #included outside of any "external declaration"; this phrase appears only this one place in C++11, so I'm not sure if it might apply here. (I'm assuming C99 has nothing to say about this.)

(For my particular case it isn't an option to use C++'s <c*> standard headers, so I really need to know the semantics only for the old-school C headers.)

like image 282
Jeff Walden Avatar asked Dec 04 '12 18:12

Jeff Walden


1 Answers

The standard doesn't say anything about C headers that are not part of C++. Previous to C++-11, stdint.h/cstdint was not part of C++. It's up to that header how it behaves when included from C++ code.

If you're asking about C headers that are part of C++, the only difference between *.h and c* is that the former isn't required to add its identifiers to the std namespace (it's optional whether it does so or not,) while the latter is required to do so (and it can optionally also add them to the global namespace.) There's no other difference. You shouldn't include a standard *.h header inside an extern "C" block, as the headers themselves take care of using C linkage where needed.

If you have non-standard C headers you want to include from C++ code, then you must inspect those headers to determine whether you need to include them extern "C" or not on a case by case basis.

like image 97
Nikos C. Avatar answered Oct 25 '22 01:10

Nikos C.