John Carter
John Carter

Reputation: 1

Can I detect (at compile time) whether I'm in an extern "C" {} block?

Say I have a C header file a.h

Any C++ header file, say a.hpp that #includes 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 #includes 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

Answers (3)

John Carter
John Carter

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

Sebastian Redl
Sebastian Redl

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

Swift - Friday Pie
Swift - Friday Pie

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

Related Questions