Reputation: 1
Say I have a C header file a.h
Any C++ header file, say a.hpp that #include
s a.h, should do so in an extern "C"
block.
So I have some header files that are common between our C++ code and C code, and I want all the C++ code to #include
a wrapper plus helpers version.
For example, if I have "a.h"
, I also have a "a.hpp"
that #include
s a.h in an extern "C"
block and adds some relevant C++ helper code.
Thus I want all C++ code to #include "a.hpp"
NOT "a.h"
.
Of course, humans being human, sometimes we forget.
The usual signal that something like that has happened is at link time, as the function name declarations are mangled and hence the link fails.
So I want something that I can put in a.h
, will fail at compile time, if a.h
is being compiled by a C++ compiler, but NOT in an extern "C"
block.
The first part of that is easy...
Just use #ifdef __cplusplus
How do I do the second part, namely detect at compile time whether I'm in a extern "C"
block?
Upvotes: 0
Views: 199
Reputation: 1
The suggestions provided by @JaMit and @Scheff's Cat, while not exactly the answer to the question, will work for the problem at hand (the question being 'how do you detect if you're in an extern "C" block').
define a macro in a.hpp (before the #include "a.h") and check whether it is defined in a.h wrapped in #ifdef __cplusplus (so that it doesn't affect the C compiler). If the check fails you could use #error to force a compiler error.
Upvotes: 0
Reputation: 71889
If you cannot modify a.h
, the question is moot.
If you can modify a.h
, it makes no sense to do something to detect wrong usage. Instead, you should make wrong usage impossible as M.M said:
// in a.h
#ifdef __cplusplus
extern "C" {
#endif
// main content here
#ifdef __cplusplus
}
#endif
Then you include a.h
and it just works.
Upvotes: 4
Reputation: 14589
There is no difference init being outside or insde of header file for compiler.Everything done before compilation and it reads a complete file.
canonical way to do it IN header file (what standard libraries often do).
// A new a.h
#ifdef __cplusplus
# define EXTERN_DECL extern "C"
# define EXTERN_SPACE_BEGIN EXTERN_DECL {
# define EXTERN_SPACE_END }
#else
# define EXTERN_DECL extern
# define EXTERN_SPACE_BEGIN
# define EXTERN_SPACE_END
#endif
EXTERN_SPACE_BEGIN
#include "lib_includes/library_a/a.h"
EXTERN_SPACE_END
If your header file is third party, se itfrom some private location lib_includes
not added to includes and have own header wrapped around it.
Note, practcally all POSIX headers do something like this with macro definitions to be compatible with C and C++ at same time.
Upvotes: 1