I needed to include a few c headers ( non standard header files ) in my C++ code to be compiled by gcc. The C header (foo.h) has support for :
#ifdef __cplusplus
extern "C" {
#endif
and similarly at the end for }. The c++ code has the include "foo.h"
I believe I should be able to just include the header (foo.h) and create instances of structs defined in the .h file.
I am not able to compile the source code. It seems like the compiler looks at the c code as if it were c++ code. I see error such as
error: expected constructor, destructor or type conversion before "("
Did I do something wrong ? I took advise from :
http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
What else do i need to do, to tell the c++ compiler "expect and compile as c code" ?
Thanks for all your replies !
My problem was i had not included all the needed header files / in the right order .
I am all set.
Related
I'm a little new to C++ and I have a question regarding converting C code into C++ code, as well as mixing C and C++ code.
For example, I'm refactoring a previous C file to a C++ file because I am now required to use a std::string in the header file's struct. It now looks as follows (firstClass.hpp):
struct firstClass
{
.
.
.
std::string test_string;
firstClass();
firstClass(const firstClass &c);
~firstClass();
};
And as a result, here's first-class.cpp:
#include "firstClass.hpp"
extern "C"
{
.
.
.
#include <errno.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
}
.
.
.
Now here's my question: I have other files that previously included firstClass.h (Note: this is the C-variant) before I converted it to C++ code -- do these files need to also be converted to C++ code? Also, if additional files include these files mentioned above will they need to be converted as well? I guess to sum up my question: after converting this initial file to C++, how far down the chain of includes do I need to also convert those files?
Most C++ compilers will process both C source code files, files with a .c extension, and C++ source code files, files with a .cpp extension. So the first step in a conversion would be to change to a C++ compiler and get your project files and/or make files in order so that it all compiles.
The next thing is to go through the source code base to determine what data structures are going to change and which include files, normally files with a .h extension, have these data structures that will need to change.
At this point you will need to begin partitioning out what source is C++ and what source is C. For instance while C struct is a subset of the C++ struct, C++ struct allows for constructors and deconstructors which C does not allow. This means you can use a C struct with C++ source but you can not use a C++ struct with the C++ features in a C source file.
Other C++ language keywords such as class just won't work period with a C source code file.
Next is to look at what C++ features, such as templates and C++ Standard Library functionality such as std::string, you are going to use. Again you will need to partition off the C++ source from the C.
The extern "C" functionality allows you to use C functions with C++ source code by declaring a function or variable name as being C rather than C++. This is necessary because the C++ compiler does name mangling, using an algorithm to generate a modified name for functions allowing function overloading. See What is name mangling, and how does it work?
The other thing you will be faced with is that C++ has introduced new versions of most of the standard C include files without the .h extension. You can use the old version with C++ but the new versions are preferred since they are for C++. However C source files can only use the old, .h extension, version of these files.
Conditional compilation for header files
The magic that allows the use of the older standard C include files with C++ source code is that most compilers have a special #define which can be used to do conditional compilation. With the Visual Studio compiler the special define is __cplusplus and it can be used something like:
#if defined(__cplusplus)
extern "C" {
#endif
// The type CONNENGINEHANDLE is for future expansion to allow multiple
// sockets to be managed by the dll.
typedef unsigned short CONNENGINEHANDLE;
// following functions are used with a server implementation.
// these functions will setup the parameters for the server and
// start the listen needed to accept a connection from a client
CONNENGINE_API int fnConnEngineSetDomainNamePort(CONNENGINEHANDLE hConnEngineSocket, char *aszDomainName, int nPortNo);
CONNENGINE_API int fnConnEngineStartEngine (int nPort, HWND hWinHandle, UINT wReceiveMsgId);
CONNENGINE_API int fnConnEngineStopEngine ();
#if defined(__cplusplus)
};
#endif
What the above preprocessor code that is part of an include file does is to allow a C++ source code file to include the same header file as C source code files but when it is included in the C++ file, the extern "C" { is part of the header file text because the Preprocessor has the __cplusplus defined. So the C++ source is able to use functions defined in the C source code and the name mangling ordinarily done with C++ is turned off for those functions whose declarations are within the braces.
However though this special #define to detect if a C++ source file is being processed by the Preprocessor you still can't use C++ language constructs in C source files. You will still need to partition out the C++ from the C.
Interface functions for C calling C++ functionality
In some cases you may need to execute C++ source code functionality from C source code functionality. In those cases you will need to create a C compatible interface to the C++ functionality.
For instance if you have a struct that contains a std::string, which is incompatible with C source code, you can create the C++ source code to hide the implementation details and to then provide a C compatible interface.
For instance from the include file example showing the use of __cplusplus above, one of those functions is defined in a C++ source code file as follows. This C++ source code file also include the same header file as would be used with a C source code file and with the declaration above for the function fnConnEngineStartEngine(), the C++ compiler knows it is not supposed to name mangle the function name fnConnEngineStartEngine{}. This C++ source code provides an interface between C source that uses the C++ object theApp.
CONNENGINE_API int fnConnEngineStartEngine (int nPort, HWND hWinHandle, UINT wReceiveMsgId)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (hWinHandle == 0)
hWinHandle = theApp.m_hWinHandle;
if (wReceiveMsgId == 0)
wReceiveMsgId = theApp.m_wReceiveMsgId;
theApp.StartEngineAsServer (nPort, hWinHandle, wReceiveMsgId);
return 0;
}
What you want to do is use a C++ compiler on the C code. The C++ compiler will process the C code just fine and handle the C++ syntax.
Not sure what compiler or IDE you're using. This can be done for many compilers by adding an argument on the command line or to build options. Or by an option in the compiler settings for an IDE.
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.
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'