I have some C code being called from C++.
The header resembles the following:
#ifndef CLibH
#define CLibH
#ifdef __cplusplus
extern "C" {
#endif
//C API
void foo(void);
// ...
#ifdef __cplusplus
}
#endif
#endif
Since I'm already using extern C,
is there any benefit to adding the nothrow compiler attribute?
#ifndef CLibH
#define CLibH
#ifdef __cplusplus
extern "C" {
#endif
//C API
void foo(void) __attribute__((nothrow));
// ...
#ifdef __cplusplus
}
#endif
#endif
Does extern C make this redundant?
Are there still advantages to applying it under these circumstances?
Yes, it does. From gcc documentation:
For example, most functions in the standard C library can be
guaranteed not to throw an exception with the notable exceptions of
qsort and bsearch that take function pointer arguments.
Related
I have a header for exporting some methods from a DLL which can be used both from C and C++ code:
#ifdef __cplusplus
extern "C"
{
#endif
API_EXPORT uint32_t __cdecl GetSomeValue();
#ifdef __cplusplus
}
#endif
and for uint32_t, I need to include a header, but which one is correct?
Option 1: <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
Option 2:
#ifdef __cplusplus
extern "C"
{
#endif
#include <cstdint>
Option 3: both.
#ifdef __cplusplus
extern "C"
{
#include <cstdint>
#else
#include <stdint.h>
#endif
You... just include the header.
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
API_EXPORT uint32_t __cdecl GetSomeValue();
#ifdef __cplusplus
}
#endif
You don't need to use extern "C" {} around built-in headers. (Sometimes you might find libraries that do need it)
Your option 2 generally will not work in conjunction with C compilers, so that's out. Your option 1, or the variation presented in #user253751's answer, should be fine, but if you are concerned with protecting against buggy C, C++, or standard library implementations then I would go with this variation on your option 3:
#ifdef __cplusplus
#include <cstdint>
extern "C"
{
#else
#include <stdint.h>
#endif
I have a .cpp file which I declare a function
#ifndef MyFile_hpp
#define MyFile_hpp
#ifdef __cplusplus
extern "C" {
#endif
void runCode();
#ifdef __cplusplus
}
#endif
#endif
This works fine. I can call this function within my Objc. In my implementation I have an extern void that it will not let me call. It's giving the undefined symbols. I need this to build as is, the extern will be declared in a different file upon compiling. Having the extern, should this compiler just trust me and let me build?
#include "MyFile.h"
extern int runMe();
#ifdef __cplusplus
extern "C" {
#endif
void runCode() {
runMe();
}
#ifdef __cplusplus
}
#endif
I think what you are doing is probably correct.
The compiler doesn't just trust you. A C++ function is declared to the linker using additional characters, or "decorations" that define the full detail of the cclass it is a member of and all its arguments. A C function has none of that, just the raw name, so it is easy for the linker to tell the difference.
I have a header that I want to include from .c and .cpp files.
so I know about name mangling and extern "C" so...
#ifdef __cplusplus
extern "C"
{
int isPrime(int64_t p);
}
#endif
but when I include this in the .c file it doesn't see the function because of the #ifdef __cplusplus
so then I end up making 2 copies:
#ifdef __cplusplus
extern "C"
{
int isPrime(int64_t p);
}
#else
int isPrime(int64_t p);
#endif
is there a better way to do this... I thought about making another header called prototypes.h and including that in those 2 places... but is there something simple I am missing?
Yes, there is a better way. People are usually doing this :
#ifdef __cplusplus
extern "C"
{
#endif
int isPrime(int64_t p);
#ifdef __cplusplus
}
#endif
If you want to do something different in c and c++ (like for example this) then you can use the 2nd syntax in your question.
Another way of doing this is as follows
// intro
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif
// content
EXTERN_C int isPrime(int64_t p);
// many other functions declared with EXTERN_C
Normally the "intro" part is placed in some common header file for everyone to use.
The advantage of this format is that each declaration is immediately seen as extern "C". A reader doesn't have to search around for possible extern "C" {
#ifdef __cplusplus
extern "C"
{
#endif
int isPrime(int64_t p);
#ifdef __cplusplus
}
#endif
That way, you can extend the int isPrime(int64_t p); part arbitrarily without repeating it in your #ifdef and #else cases.
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.