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
Related
I am very new to C++ and I'm trying to do my best to have a good project structure from the beginning.
I am using the C library libjpeg and was including it in my .cpp with the use of
extern "C" {
#include <jpeglib.h>
}
It worked fine until I removed it to put it in a header file which now gives me the following errors:
inc/jpeg_utils.h: 6: inc/jpeg_utils.h: extern: not found
inc/jpeg_utils.h: 8: inc/jpeg_utils.h: Syntax error: "}" unexpected
My headerjpeg_utils.h :
#ifndef JPEG_UTILS_INCLUDE
#define JPEG_UTILS_INCLUDE
#include <stdio.h>
extern "C" {
#include <jpeglib.h>
}
int read_jpeg_file(char *filename, int decompression);
void write_jpeg_file(char *filename, unsigned char *image_buffer, int image_width, int image_height, int quality);
#endif
And at the top of jpeg_utils.cpp :
#include "../inc/jpeg_utils.h"
Did I misunderstand the use of a header ?
If you include jpeg_utils.h in a C file, that extern "C" directive will not compile (obviously, C is not C++).
Add a pre-processor directive to extern "C" only when in fact you compile as C++.
#ifdef __cplusplus
extern "C" {
#endif
#include <jpeglib.h>
#ifdef __cplusplus
}
#endif
I recently saw this block at the beginning of a .h file.
#ifdef __cplusplus
extern "C" {
#include <cstddef>
#include <cstdint>
#else
#include <stddef.h>
#include <stdint.h>
#endif /* __cplusplus */
Does wrapping a #include directive for a standard C++ header in extern "C" { ... actually do anything? Is it functionally different from:
#ifdef __cplusplus
#include <cstddef>
#include <cstdint>
extern "C" {
#else
#include <stddef.h>
#include <stdint.h>
#endif /* __cplusplus */
I was under the impression that this makes no difference, but I'm seeing it so often I am becoming curious.
Based on the "If ...def" statement in that header file, the
"if" block : "if you use the particular header file in C++"
"else" block : "if you use the particular header file not in C++, could be C"
if you do not wrap the headers in "extern C" in the "if" block(which is meant for C++), the "C" linkage wont be maintained for the function names.
"C" do not have function over loading concept, but where as C++. So C++ compiler does some function name mangling for "extern C" functions.
Here is a very nice article.
In C++ source, what is the effect of extern āCā? - in stack over flow.
For regular standard C libraries, the extern wrapper not required. Mostly it is taken care by standard C.
ex: something like below (yvals.h on windows).
#define _C_LIB_DECL extern "C" { /* C has extern "C" linkage */
#define _END_C_LIB_DECL }
#define _EXTERN_C extern "C" {
#define _END_EXTERN_C }
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.
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 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.