I found some code recently where extern "C" was added in source file also for functions. They were also added in the header files where they were declared.
I was under the assumption that adding 'extern "C" in header files was sufficient.
Where should extern "C" blocks be added?
UPDATE:
Suppose I am compiling my C code using a CPP compiler and have added extern "C" guards for all the functions in header files (i.e. all my functions have their prototypes in headers), but in source files I have not added the same. Will this cause a problem?
Since you mean
extern "C" { ... }
style guards, these declare some functions to be of "C" linkage, rather than "C++" linkage (which typically has a bunch of extra name decoration to support things like overloaded functions).
The purpose, of course, is to allow C++ code to interface with C code, which is usually in a library. If the library's headers weren't written with C++ in mind, then they won't include the extern "C" guards for C++.
A C header written with C++ in mind will include something along the lines of
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
to make sure C++ programs see the correct linkage. However, not all libraries were written with C++ in mind, so sometimes you have to do
extern "C" {
#include "myclibrary.h"
}
to get the linkage correct. If the header file is provided by someone else then it's not good practice to change it (because then you can't update it easily), so it's better to wrap the header file with your own guard (possibly in your own header file).
extern "C" isn't (AFAIK) ANSI C, so can't be included in normal C code without the preprocessor guards.
In response to your edit:
If you are using a C++ compiler, and you declare a function as extern "C" in the header file, you do not need to also declare that function as extern "C" in the implementation file. From section 7.5 of the C++ standard (emphasis mine):
If two declarations of the same
function or object specify different
linkage-specifications (that is, the
linkage-specifications of these
declarations specify different
string-literals), the program is
ill-formed if the declarations appear
in the same translation unit, and the
one definition rule
applies if the declarations appear in
different translation units. Except
for functions with C++ linkage, a
function declaration without a linkage
specification shall not precede the
first linkage specification for that
function. A function can be declared
without a linkage specification after
an explicit linkage specification has
been seen; the linkage explicitly
specified in the earlier declaration
is not affected by such a function
declaration.
I'm not convinced it's good practice though, since there's the potential for the linkage specifications to diverge by accident (if, for example, the header file containing the linkage specification isn't included in the implementing file). I think it's better to be explicit in the implementation file.
They only need to go in anything that is included by other source files.
With some idioms you'll find people including source files.
They should be added to all files, that get included in other files.
Normally, one doesn't include source files.
Apologia
The question has changed to be much clearer what it was asking about. This answer addressed the original question, when it was at least debatable whether it was discussing guards against multiple inclusion in header files - which is what my answer addresses. Clearly, if the question had been as clear then as it is now, I would not have submitted this answer.
Original answer
No, it is not necessary to include the guards in the C code too.
If the header file 'header.h' says:
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
...
#endif
Then it is perfectly safe for a source file 'source.c' to say:
#include "header.h"
It is also safe for other headers to include 'header.h'.
However, people note that opening a header file and reading it takes time, which slows up a compilation, so sometimes people do things like:
#ifndef HEADER_H_INCLUDED
#include "header.h"
#endif
This means that if some other header included in 'source.c' has already included 'header.h', then the '#include' is not re-processed. (Or, if 'header.h' has already been included directly in 'source.c', though that's a silly buglet.)
So, when encountered, it is likely to be an attempt to optimize the compilation performance. It is far from clear that it buys you much; modern C preprocessors are fairly intelligent about the issue and will avoid re-including the file if they can. And there's always a risk that the test in 'source.c' has a typo (#ifndef HEARER_H_INCLUDED, perhaps) in which case the test slows the compilation because the preprocessor tests the irrelevant condition and then proceeds to include 'header.h' after all. It is 'safe'; the header is itself protected-- or should be.
If you see the code in 'source.c' also doing '#define HEADER_H_INCLUDED', then there are problems. The #define has to be either before or after the #include, and neither is good as a general technique.
If 'source.c' does '#define HEADER_H_INCLUDED' before including 'header.h', then if the guard appears in 'header.h', the contents of the header will not be included. If the guard does not appear in 'header.h', then things work OK.
If 'source.c' does '#define HEADER_H_INCLUDED' after including 'header.h', then if the guard appears in 'header.h', we get a benign redefinition of HEADER_H_INCLUDED. If 'header.h' does not contain the guard but does include a file which includes 'header.h', you are not protected from multiple inclusion after all.
Note that body of the header appears after the '#define HEADER_H_INCLUDED'. This is again protection if nested includes include 'header.h'.
You mean the 'extern c' preprocessors? They have to be on the function definition as well as that affects how the function call is stored in the compiled binary. Its only really needed if you are linking compiled c++ together with c which is compiled as C (as opposed to c in a .cpp file).
The "C" guards have two purposes:
When your code is compiled, the functions will be exported in a way that will allow a non C++ compiler/linker to use them (no C++ name mangling etc.)
When a C++ compiler uses your header files, it will know that it should bind the symbols in the C way which in turn will make sure that the resulting program will link successfully. They don't carry a meaning for a non C++ compiler but since the symbols were generated in C-style in (1) this is the desired effect.
Since you include the header with the "C" guards also in your implementation file, the information on how the symbols should be created at compile time is available to the compiler and the compiler will create the symbols in a way that can be used by a non C++ compiler. Consequently you only need to specify extern "C" in your header file as long as the header file is also included by the implementation file.
it is not required for extern to be used in source files, if they are used in the header file and that file is included by the rest of the source files.
As far as I remember the standard, all function declarations are considered as "extern" by default, so there is no need to specify it explicitly. That doesn't make this keyword useless since it can also be used with variables (and it that case - it's the only solution to solve linkage problems). But with the functions - yes, it's optional.
A little more verbose answer is that it allows you to use variables compiled in another source code file, but doesn't reserve memory for the variable. So, to utilise extern, you have to have a source code file or a library unit that contains memory space for the variable on the top level (not within functions). Now, you can refer to that variable by defining an extern variable of the same name in your other source code files.
In general, the use of extern definition should be avoided. They lead easily to unmanagable code and errors that hard to locate. Of course, there are examples where other solutions would be impractical, but they are rare. For example, stdin and stdout are macros that are mapped to an extern array variable of type FILE* in stdin.h; memory space for this array is in a standard C-library unit.
We had always only added extern "C" to the header definitions, but this allows the C++ code to implement the function with a different signature via overloading without errors and yet it doesn't mangle the symbol definition so at link times it uses this mismatching function.
If the header and the definition both have extern "C" then a mismatched signature generates an error with Visual Studio 2017 and with g++ 5.4.
This following code compiles without an error for Visual Studio 2017 and g++ 5.4
extern "C" {
int test(float a, int b);
}
int test(int b)
{
return b;
}
It seems that gcc mangles the symbol name in this case but Visual Studio 2017 does not.
However including the extern "C" with the definition catches the mismatch at compile time.
extern "C" {
int test(float a, int b);
}
extern "C" int test(int b)
{
return b;
}
gives the following error on g++:
g++ -c -o test.o test.cpp
test.cpp: In function ‘int test(int)’:
test.cpp:4:26: error: conflicting declaration of C function ‘int test(int)’
extern "C" int test(int b)
^
test.cpp:2:9: note: previous declaration ‘int test(float, int)’
int test(float a, int b);
or with cl
cl /c test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27042 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(4): error C2733: 'test': second C linkage of overloaded function not allowed
test.cpp(2): note: see declaration of 'test'
Related
I have a C++ file that compiles fine in one project, but not in another. The file is the exact same C++ file in both projects.
Both projects are MFC dialog-based projects. They have slightly different stdafx.h files... but if I'm prepared to break the rest of the project, I can make them identical... and still get this compiler error. Equally, they have considerably different include paths, but if I break even more of the project and make the include paths identical, I still get the error. It goes without saying that I have made all my preprocessor directives identical... and I still get the error.
So, as far as I can tell, I'm down to compiler switches. I've made them identical (within reason - I haven't bothered to change the /Fp, /Fd or /Fo output files), but still it refuses to compile. Are there any "hidden" settings or anything else that might be affecting compilation?
[Note: the following is included mostly for historical reasons - it led to an unintentional over-emphasis when this question was originally posed, and so led to predictable comments and answers which didn't help resolve the intended "when is identical not identical?" question]
The error itself is error 2894 (templates cannot have 'C' linkage). I understand this error, but not how/why it is occurring. It occurs within a bunch of C header files pertaining to a C library. They are all neatly wrapped in extern "C" {...} declarations, with #ifdef __cplusplus correctly applied. But extern C {...} is not something I'm very familiar with, so... is there anything special about extern "C" {...} that might be a factor?
If a single C++ file is compiled under the same conditions, it leads to the same result. It doesn't matter if it is in a project with zero other files, or a hundred other files - the compiler compiles each file individually.
Therefore, if a single C++ file compiles with different results, then that is either because:
It is not really the same single C++ file, or
It is not really the same compilation conditions.
You can see exactly what the Microsoft Visual C++ compiler thinks your "single" C++ file truly is by specifying /showIncludes as an "advanced" compiler option. You might be surprised to see how different your "identical" C++ file is (and this was the case here).
Equally, you can see the explicit C++ compiler conditions listed under the Command Line summary that appears at the bottom of the list of C/C++ options in the project properties in Visual Studio.
wspapi.h includes some C++ template code outside of its internal extern "C" section. If you were to externally wrap the header in an extern "C" declaration, you would break it.
For example, you cannot do this:
extern "C"
{
#include <wspapi.h>
}
Similarly, if a preceding header or code has failed to terminate an extern "C" block so that all the content of the header is given C linkage, the same situation arises.
Put simply, wpsapi.h has been included within a C linkage block, it has nothing to do with "hidden options".
I am relatively new to Mixed C/C++ applications using the gcc and g++ tools.
To get the hand of it I have downloaded the iperf source code and built it with success using Eclipse.
There is one oddity: If I look into the file "Thread.c" using Eclipse it thinks there is a syntax error and underlines almost the whole file as if the code is flawed, which it is absolutely not.
This is the piece of code that triggers it:
#ifdef __cplusplus
extern "C"
{
#endif
I know what extern "C" is used for in C++ but Eclipse has problems with it when present in .c files. It happily accepts it in .cpp and .h files though.
I have checked out how the Make utility builds the iperf application and I see it always uses gcc to compile c files and g++ to compile cpp files which makes me wonder if extern "C" is actually required. It most definitely does not hurt because the gcc compiler happily deals with it but if it is not strictly required I could omit it and get better readability in Eclipse.
I have also looked at a possible solution for Eclipse's behaviour but have not really found one, if anybody can point out how to solve it that would be equally good.
If you are using Eclipse, what you seeing in editor has to do with Eclipse internal indexer/parser. Your mixed C/C++ project may compile and build with no issues, but when you open a source file which has
#ifdef __cplusplus
extern "C" {
#endif
you may see a syntax error marked on the extern "C" line. This means that "__cplusplus" symbol is defined for your C compiler in your project settings.
In order to get rid of that syntax error in the Eclipse editor, go to project Properties -> C/C++ General -> Paths and Symbols -> # Symbols tab, and select "GNU C" (or whatever C compiler you use) under "Languages" column. Scroll through Symbol/Value list on the right, find the "__cplusplus" symbol and delete it. Make sure you do that only for C compiler.
Click OK to close the project Properties window and the syntax error warning will be gone in Eclipse editor.
that piece of code is normally found in headers, and should be always be written to header files that belong to c-files. (with the corresponding closing bracket at the end of the header)
reason is, that c uses a different scheme how the functions are internally called (--> name mangeling). while the compiler can distinguish a c++ code file from c code file by its extension it can not distinguish between a c-header and a c++ header that is included from a cpp file. so it does not know if it has to mangle the name of the declared functions or not (by default it does).
then the linker tries to match the used symbols (reference to function from cpp) with the created one (defined by the c-file) it does not find the symbol if the compiler was not told not to mangle the declaration.
extern "C" is only legal in C++ and ensures that the specified function(s) have C linkage. This means that the function parameters are not mangled into the binary function name.
To ensure that the header file compiles in C we include the #ifdef __cplusplus __cplusplus is defined by a C++ compiler and not a C compiler. This use used to protect C code from the C++ only extern "C" directive.
IDE's so not use compilers for code intelligence and therefore may get things wrong.
probably just a silly workaround for your issue.
what i found is that, while using c functions in cpp file, theoretically extern is required.
But i found that in eclipse oxygen version, we do not have to specify extern c, we can directly use c functions and printf statements too in cpp file and it just works fine.
Havent tried in older versions of eclipse.
My solution may not be very helpful, but you could give it a try. It worked for me.
I have a library written by a not very meticulous coder, which includes the following code in a C header file:
/* SomeCHeaderFile.h */
...
#define local static
#define package
#define global
When this file is included in a C++ header, for example:
EDIT: I forgot to mention that I include the header like so:
// SomeCPlusplusSourceFile.cpp
extern "C" {
#include "SomeCHeaderFile.h"
}
...
the compiler gives the following error:
error: constructor cannot be static member function
error: 'std::locale::locale(const std::locale&)' cannot be overloaded
error: with 'std::locale::locale(const std::locale&)'
I only say the coder was not meticulous because she/he never tested it in a C++ code. But I don't know the reasoning behind this to why is this causing the build to fail?
gcc version 4.4.3 | ubuntu linux
It seems the troublesome C header file is redefining tokens in use by the standard C++ header files. If you want to use the C header file in your C++ code, you may be required to include it after the standard header files to prevent this kind of problem.
This may not sufficiently guard you from problems if the C++ code defines its own macros that also redefine the same tokens. If that happens, you will have to segregate your C++ code with files dedicated to C++ that uses the troublesome C header file and C++ code that does not. The C++ code that does use the troublesome C header file makes sure to not use any C++ header file that would cause problems.
You can use C header files in CPP files as follows:
extern "C" {
//Headers go here
}
More details here:
In C++ source, what is the effect of extern "C"?
What I want to do:
I have autogenerated C Code generated with Matlab Simulink and want to enhance it with some more functionality written in C++. To be exact, the C code calls a C-style API that internally uses C++. The whole thing is in a VS 2008 C++ project.
The problem:
It compiles, as long as I tell VS to compile it as C and leave out my C++ code. As soon as I compile it as C++ problems arise.
First of all, I can't compile it as C++ because math.h produces an error C2668 due to an ambiguous call to an overloaded function (fabs()).
If I now additionally add some C++, e.g. include iostream, I get hundreds of compiler errors complaining about missing curly braces and misplaced colons somewhere in cstdlib.
My question:
How can I mix the two languages in a way that works? I read about preprocessor defines (http://www.parashift.com/c++-faq-lite/overview-mixing-langs.html) but I don't know how to apply them correctly to solve my problem.
Any help is greatly appreciated!
It seems you are including C++ headers in your C source code. Probably indirectly by including it in other header files (i.e. the C source include your C++ header, and the C++ header includes other C++ header files).
There are two ways of solving this:
Use the preprocessor to conditionally include the C++ headers only when compiled in C++. This can be done like
#ifdef __cplusplus
# include some_cpp_header
#endif
Don't include C++ headers (directly or indirectly) in your header files. Or better, make a separate header file whose only purpose is to be included in the C source, and which only contains the function prototypes (with extern "C" when compiled as C++) of the API. The body of the header file could look like this
#ifdef __cplusplus
extern "C" {
#endif
void function1(int);
int function2(const char*);
/* More function prototypes */
#ifdef __cplusplus
}
#endif
I recommend the second method.
Include the <iostream> library and then you'll have to compile your code with a c++-compiler.
I have a question about Preprocessor directives in C and C++.
I have the following code:
#ifdef __cplusplus
//part A
extern "C"
{
// somecode here
}
#else
//part B
#endif
I know the c++ complier predefined the __cplusplus will c compiler does not.
And I put this set of code into a c header file, and c++ file will include this c header file. And my question is: if the file is compiled by a c++ compiler, it will compile the part A, and if it is compiled by a c compiler, it will compile the part B, but normally, we use this code to make c++ file and c file interact with each other, if we have such code above, I mean we have both C and C++ file together, and we use gcc compiler, how this code is compiled? only part A is compiled? or only part B is compiled? or the code is devided into two parts, part A is compiled for C++ and part B is compiled for C file at the same time?
if we have such code above, I mean we have both C and C++ file together, and we use gcc compiler, how this code is compiled? only part A is compiled? or only part B is compiled?
That depends on how the translation unit that #includes the header is being compiled. If it's being compiled as C++, then part A will take effect; if it's being compiled as C, it will be part B.
With gcc, the language is either determined by the file extension, or can be explicitly specified on the command line:
-x language
Specify explicitly the language for the following input files (rather than letting the compiler choose a default based on the
file name suffix). This option applies to all following input files
until the next -x option.
Possible values for language are: c
c-header c-cpp-output c++ c++-header c++-cpp-output objective-c
objective-c-header objective-c-cpp-output objective-c++
objective-c++-header objective-c++-cpp-output assembler
assembler-with-cpp ada f77 f77-cpp-input f95 f95-cpp-input java
Direct answer: only the part appropriate to the current compiler invocation is compiled.
Typically the structure is
#ifdef __cplusplus
extern "C" {
#endif
/* Definitions here */
#ifdef __cplusplus
}
#endif
in the header file. So you get compatible definitions in both languages. The implementation file would then be pure C and stored in a .c file.
In a project with multiple source files, the header is not processed just once by the compiler.
When the compiler compiles a C++ file, it reads that file and any headers it includes (directly or indirectly) and processes the contents of those files using the rules for C++.
When the compiler compiles a C file, it reads that file and any headers it includes (directly or indirectly) and processes the contents of those files using the rules for C.
The result will be as if the code in your header file appeared separately in the C++ source and in the C source.
By default gcc will recognize .C, .cpp, .cc and a few other extensions as C++ and .c as C. You could try funkier things in your make file to force it through each way but in the simple case, it's this simple.
Conceptually C++ is converted into C code by mangling identifiers. This will effect the linking. (in fact this was how it was done in the past and if memory serves me right it was done by CFront.
So having
#ifdef __cplusplus
extern "C" {
#endif
/* Definitions here */
#ifdef __cplusplus
}
#endif
You have the same definitions for both C and C++. You do not want different ones (Part A & B in your question) as that is silly. You just what the same if you use it for C and C++.
The extern "C" bit tells the C++ compiler to ensure that the linking is for object code compiled for C - therefore do not do the C++ magic and thus ensure that the linking will work.