I'm writing a C library, which may potentially be useful to people writing C++. It has a header which looks like this:
#ifndef FOO_H_
#define FOO_H_
#include <bar.h>
#include <stdarg.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void foo_func();
#ifdef __cplusplus
}
#endif
#endif
and I was wondering - should I move the extern "C" bit before including the header include directives? Especially seeing how, in practice, some of those headers might themselves have an extern "C"?
NO, in general you shouldn't move it to include the headers.
extern "C" is used to indicate that the functions is using the C calling convention. The declaration has no effect on variables and #defines, so there is no need to include these. If an #include is inside an extern "C" block, this effectively modifies the function declarations inside that header file!
Background: Without the extern "C" declaration, when compiling using a C compiler, a function is assumed to follow the C convention, and when compiling using a C++ compiler, the C++ convention is assumed. In case the same header file is used for C and C++ code, you would get a linker error, since the compiled function has different names in C and C++.
Although it's possible to put all your code between the #ifdef blocks, I personally don't like it, because it's really only intended for the function prototypes, and I frequently see people copy-pasting this at places where it shouldn't be. The cleanest way is to keep it where it's supposed to be, which is around the function prototypes in a C/C++ header file.
So, to answer your question "should I move the extern "C" bit before including the header include directives?", my answer is: No, you shouldn't.
But is it possible? Yes, and in many cases this won't break anything. Sometimes it is even necessary, if the function prototypes in an external header file are incorrect (e.g. when they are C functions and you want to call them from C++) and you cannot change that library.
However, there are also cases where doing so breaks the build. Here's a simple example that fails to compile if you wrap the include using extern "C":
foo.h:
#pragma once
// UNCOMMENTING THIS BREAKS THE BUILD!
//#ifdef __cplusplus
//extern "C" {
//#endif
#include "bar.h"
bar_status_t foo(void);
//#ifdef __cplusplus
//}
//#endif
foo.c:
#include <stdio.h>
#include "foo.h"
#include "bar.h"
bar_status_t foo(void)
{
printf("In foo. Calling bar wrapper.\n");
return bar_wrapper();
}
bar.h:
#pragma once
typedef enum {
BAR_OK,
BAR_GENERIC_ERROR,
BAR_OUT_OF_BEAR,
// ...
} bar_status_t;
extern "C" bar_status_t bar_wrapper(void);
bar_status_t bar(void);
bar.cpp:
#include <iostream>
#include "bar.h"
extern "C" bar_status_t bar_wrapper(void)
{
std::cout << "In C/C++ wrapper." << std::endl;
return bar();
}
bar_status_t bar(void)
{
std::cout << "In bar. One bear please." << std::endl;
return BAR_OK;
}
main.cpp:
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
#include "bar.h"
int main(void)
{
bar_status_t status1 = foo();
bar_status_t status2 = bar();
return (status1 != BAR_OK) || ((status2 != BAR_OK));
}
When uncommenting the blocks in a.h, I get the following error:
main2.cpp:(.text+0x18): undefined reference to `bar'
collect2.exe: error: ld returned 1 exit status
Makefile:7: recipe for target 'app2' failed
Without, it builds fine. A C main calling only C functions from foo and bar will build fine either way, since it's unaffected by the #ifdef __cplusplus blocks.
Surprisingly yes. After reading the standard now even I would write
#ifndef FOO_H_
#define FOO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <bar.h>
#include <stdarg.h>
#include <stddef.h>
void foo_func();
#ifdef __cplusplus
}
#endif
#endif
For 2 reasonss:
1 Having nested extern "C" are no problem, so your bar.h include would be fine. Like this it looks clearer and more important
2 To be really portable your surprisingly have to wrap an extern "C" around your C headers for C++ users, if they don't want to.
Because I just looked thru the C++ Standard and 16.5.2.3 Linkage [using.linkage] states
Whether a name from the C standard library declared with external linkage has extern
"C" or extern "C++" linkage is implementation-defined. It is
recommended that an implementation use extern "C++" linkage for this
purpose.1
To be safe than sorry, you indeed should wrap an extern "C" around those includes but, you should not have to, since this implies to the headers in D.9 C headers [depr.c.headers] like <stdlib.h> which you are using.
This is covered in the C++ FAQ.
First, How to include a standard C header file in C++ code? Nothing special is needed, as standard C header files work seamlessly with C++. So you don't need to wrap stdarg.h and stddef.h in extern "C".
Then, for non-standard C headers, there are two possibilities: either you can’t change the header, or you can change the header.
When you can't change the C header, wrap the #include in extern "C".
// This is C++ code
extern "C" {
// Get declaration for f(int i, char c, float x)
#include "my-C-code.h"
}
int main()
{
f(7, 'x', 3.14); // Note: nothing unusual in the call
// ...
}
When you can change the header, edit it to conditionally include extern "C" in the header itself:
#ifdef __cplusplus
extern "C" {
#endif
. . .
#ifdef __cplusplus
}
#endif
In your case it comes down to whether you have control over the contents of bar.h. If it's your header, then you should modify it to include extern "C" and not wrap the #include itself.
Headers should work the same way regardless of how/when/where they are included. Wrapping an #include in extern "C", #pragma pack, special #defines, etc, should be reserved for last resort workarounds, as this may interfere with how the header behaves in different scenarios, reducing the system's maintainability in the long run.
As StoryTeller said in the comments:
Some headers are explicitly written under the assumption that the outermost "scope" has C++ language linkage. They may use __cplusplus to remove template declarations, and if you wrap them up like you wish to, your header will be fundamentally broken. So as mentioned already, make your declarations correct, and let other headers do their thing unimpeded. Even standard library headers may break (since an implementer may reason its going to be shared anyway, and then do some expert friendly things inside).
Note that standard C headers may be implemented using C linkage, but may also be implemented using C++ linkage. In which case wrapping them in extern "C" might result in link errors.
I am using standard CPP to preprocess any C/CPP file.
I am using the below command for preprocessing:
cpp -idirafter <path_to_header_files> -imacros <sourcefile> <source_file> > <destination_file>
The above command is replacing all the macros with its corresponding implementations defined in header files.
If I want some specific MACROS containing a particular string (eg, ASSERT) should not replace by cpp preprocessor. ie, if any macro defined by the name of TC_ASSERT_EQ or TC_ASSERT_NEQ defined in some header files should not replace by preprocessor.
Is there any ways I can control this?
You can use predefined macros to work around this. You can pass different defines to cpp and gcc/g++ using -D parameters
For example your assertion header can look like my_assert.h:
#ifndef __my_assert_h__
#define __my_assert_h__
#if defined ASSERT_DEBUG
#define my_assert(expr) my_assert(expr) /* please dont touch my assertions */
#else
#define my_assert(expr) ((void)0U) /* Your assertion macro here */
#endif /* ASSERT_xxx */
#endif /* #ifndef __my_assert_h__ */
And your source files can be as before. For example test.c:
#include "my_assert.h"
#include <stdio.h>
void foo (int p) {
my_assert(p==1);
puts("Tralala\n");
}
int main (void) {
foo(1);
return 0;
}
With the above trick you can run
cpp -DASSERT_DEBUG test.c
While the compilation still works as before.
gcc test.c
I have used #pragma poison TC_ASSERT_EQ statements to pass the line without preprocessing.
i have header file as follows
**something.h**
#ifdef __cplusplus
extern "C" {
#endif
blah
blah
extern CONST oMenu_t const menu[];
blah
blah
#ifdef __cplusplus
}
#endif
though i have used appropriate(i suppose) extern "C" still facing error "type qualifier specified more than once" while compiling with c++ compiler..
help please
multiple const is not needed
you may use:
extern oMenu_t const menu[];
in your .h file.
However, you must have something like below in one .c file (define only once, declare as many times, as used in .h)
oMenu_t const menu[] = {....}; // appropriate initializer
Add
#ifndef __FILENAME_HEADER_FILE
#define __FILENAME_HEADER_FILE
your existing head file goes here...
#endif // __FILENAME_HEADER_FILE
around your header file, this means you can include the .H many times but the compiler only sees it once.
FYI: Replace FILENAME with the name of your filename, the #define this needs to be different in each header file you use it.
I have one file example1.cpp with the main function. This file must have #include mylib.h and #include lib.h. File mylib.h also has #include lib.h. When I try to compile this program, the error redefinition xyz function ocurs.
example1.cpp
#include mylib.h
#include lib.h
int main(){
//code
}
mylib.h
#include lib.h
//rest code
You need to put include guards in your header file to prevent it from getting included multiple times during compilation.
#ifndef LIB_H
#define LIB_H
// Actual header file code
#endif
You have to wrap the .h files in #defines to avoid the redifinitions. For example:
#if !defined(_MY_LIB_H_)
#define _MY_LIB_H_
// Add your function definitions here...
#endif // _MY_LIB_H_
You can now include it anywhere and the function definition will be read once. Also note that you can use #ifndef depending on the compiler. VC++ for example, allows "#pragma once" if it's version 10 or higher:
#if _MSC_VER > 1000
#pragma once
#endif
In this case, you don't need to use the #defines explained above.
I need to create structure like this:
// file main.h:
#pragma once
#ifndef _MAIN_H
#define _MAIN_H
#include <iostream>
#include "first.h"
#include "second.h"
#endif
// -----------------
// file first.h:
#pragma once
#ifndef _FIRST_H
#define _FIRST_H
#include "main.h" // because of using SomeFunction() in first.cpp
int SomeVar; // used in first.cpp
#endif
// -----------------
// file second.h:
#pragma once
#ifndef _SECOND_H
#define _SECOND_H
#include "main.h" // because of using SomeVar in second.cpp
int SomeFunction(); // implemented in second.cpp
#endif
// -----------------
By logic, if main.h will be compiled first, then each of this headers will be included only once and all variables/functions will be defined normally.
For example, this configuration compiled normally in IAR C++ Compiler, if set up in options "preinclude file" (not precompiled) to main.h.
But, in Visual Studio 2010 same structure causes linker errors like:
1>second.obj : error LNK2005: "int SomeVar" (?SomeVar##3HA) already defined in first.obj
1>second.obj : error LNK2005: "int SomeFunction" (?SomeFunction##3HA) already defined in first.obj
I think because of including files in alphabetic order. Apparently pragma- and define-guards are ignored by linker.
Errors can be fixed by additional header and external variables definitions, but this is hard and wrong way.
Question is: What should i do?
int SomeVar; // used in first.cpp
Variables should never be defined in headers. They should be declared with extern:
extern int SomeVar; // used in first.cpp
Then you can actually define them in "first.cpp" with int SomeVar;.
Also, "first.h" does not need to include "main.h". Headers should only include files if the definitions in that header absolutely need the contents of those files. The definitions in "first.h" do not need anything in "main.h". Therefore, it should not include it.
If "first.cpp" needs to include something from "second.h", then it is the responsibility of "first.cpp" to include it.
In the header file use extern keyword as:
//first.h
extern int SomeVar; //extern tells the compiler that definition is elsewhere
Then in .cpp file define it and use it:
//first.cpp
int SomeVar; //definition is here
As for SomeFunction, have you defined it header file itself? Re-check it. :-)