How do I test to see if I am linking in C++ or C using macros?
Say I have code that should link as C in a C++ file, I would use extern "C"{//code here}which would make my code in a link as C . How would I set up my name.c file to work for both C and C++. Something like...
#ifdef C++//or other macro
extern "C"{
#endif
#ifdef C++
}
#endif
What is the proper macro to replace the "C++" I have above, and will it be cross platform? or how can I set it up to be cross platform?
Also, What is the significance of having to do the extern "C"{} for C code in a C++ file?
Any help is appreciated. Thanks in advance.
"What is the proper macro to replace the "C++""
It's #ifdef __cplusplus
#ifdef __cplusplus
extern "C"{
#endif
//.....
#ifdef __cplusplus
}
#endif
For "...What is the significance of having to do....?"
Read : In C++ source, what is the effect of extern āCā?
Related
I have a C header as part of a C++ library.
This C header would only make sense compiled by a C compiler, or by a C++ compiler within an extern "C" { ... } block, otherwise unresolved link errors would happen.
I thought to add a block such as:
#ifdef __cplusplus
#error "Compiling C bindings with C++ (forgot 'extern \"C\"'?)"
#endif
in the C header, but unfortunately the __cplusplus macro is defined also within an extern "C" { ... } block.
Is there another way to detect this condition correctly?
The common practice is not to demand client code wraps your header in extern "C", but to do so conditionally yourself. For instance:
#ifdef __cplusplus
extern "C" {
#endif
// Header content
#ifdef __cplusplus
}
#endif
That way client code is automatically correct without doing anything beyond including the header.
I understand that when you include a c header in your c++ project you must wrap it with extern "C" because c++ and c have two different ways of identifying function. c will use the name to identify a function and c++ must use the name and the parameters to satisfy function overloading.
What I don't understand is why are there are c headers that don't require to be wrapped in extern "C" like windows.h??
In general, wrapping a C header in extern "C" is not a good idea. The header might include other files that break when you do this. A C header that is designed to be used in C++ will handle extern "C" appropriately, without you having to do anything. Typical code:
#ifndef MY_HEADER_INCLUDE_GUARD
#define MY_HEADER_INCLUDE_GUARD
#ifdef __cplusplus
extern "C" {
#endif
/* C callable stuff goes here */
#ifdef __cplusplus
}
#endif
#endif /* MY_HEADER_INCLUDE_GUARD */
This question already has answers here:
What is the effect of extern "C" in C++?
(17 answers)
Closed 6 years ago.
I see some code in C++ using extern "C" at the beginning of the file like this:
#ifdef __cplusplus
extern "C" {}
#endif
What does this mean? How does it work?
It is used to inform the compiler to disable C++ name mangling for the functions defined within the braces. http://en.wikipedia.org/wiki/Name_mangling
It's probably not like that, but more like:
#ifdef __cplusplus
extern "C" {
#endif
//some includes or declarations
#ifdef __cplusplus
}
#endif
It tells the compiler to use C name mangling for whatever is declared inside the directives.
The way you have it now:
#ifdef __cplusplus
extern "C" {}
#endif
is just dead code.
Extern "C" - notify the compiler,that the noted function is compiled in C style.
It specifies a linkage specification.
It tells the linker how to link the code.
It is useful when you want to mix C and C++ code.
I just got some C code that uses extern "C" to declare external functions like this:
extern "C" void func();
Is this valid C? I'm getting an error at this line, but I'm not sure if it's because of this or something else.
No, it's not valid C. It should only be used in C++ code to refer to functions defined in C code. The extern "C" should be surrounded in a ifdef __cplusplus/#endif block:
// For one function
#ifdef __cplusplus
extern "C"
#endif
void func();
// For more than one function
#ifdef __cplusplus
extern "C"
{
#endif
void func1();
void func2();
#ifdef __cplusplus
}
#endif
this is a C++ notation to tell the compiler/linker to use C calling standards.
Usually that line is wrapped in an pre-processor statement.
#ifdef __cplusplus
extern "C" {
#endif
// stuff
#ifdef __cplusplus
}
#endif
Not valid in C. If present after preprocessing this will result in a diagnostic as per the standard.
For C++, this turns of name-mangling. See this for more details as to why it may be required. Can you post some more details?
I am writing a (my first) C++ class on top of some code written in C, but I can only get the C++ to compile by declaring the C functions in a extern block. My project uses autotools; is there any way to automate this process so I don't have to maintain two header files?
Use a extern block inside a #ifdef in C codes header files
Start of header files
#ifdef __cplusplus
extern "C" {
#endif
...and at end of the header files
#ifdef __cplusplus
}
#endif
This way it will work for being included in both C and C++ sources
Yes create wrapper header files which include your C header files like so...
//Wrapper.h
#ifdef __cplusplus
extern "C"
{
#include "Actual.h"
}
#else
#include "Actual.h"
#endif
//Use.cpp
#include "Wrapper.h"
int main()
{
return 0;
}
//Use.c
#include "Wrapper.h"
/*or #include "Actual.h" */
int main()
{
return 0;
}
Use the C Preprocessor. Do something like this:
#ifdef __cplusplus
extern "C" {
#endif
// code goes here
#ifdef __cplusplus
}
#endif
We have a macro in a header file:
#ifdef __cplusplus
#define _crtn "C"
#else
#define _crtn
#endif
Then in header files, we can use _crtn:
#include "croutine.h"
extern _crtn void MyFunction( ... );
The only gotcha is to make sure you include the header file containing the prototype of MyFunction inside the file containing the implementation of MyFunction so that it is compiled with "C" linkage.
This is the same as #epatel's answer, but only requires the ugly #ifdef's in one header file.