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.
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"?
Just a small question:
Can C++ use C header files in a program?
This might be a weird question, basically I need to use the source code from other program (made in C language) in a C++ one. Is there any difference between both header files in general? Maybe if I change some libraries...
I hope you can help me.
Yes, you can include C headers in C++ code. It's normal to add this:
#ifdef __cplusplus
extern "C"
{
#endif
// C header here
#ifdef __cplusplus
}
#endif
so that the C++ compiler knows that function declarations etc. should be treated as C and not C++.
If you are compiling the C code together, as part of your project, with your C++ code, you should just need to include the header files as per usual, and use the C++ compiler mode to compile the code - however, some C code won't compile "cleanly" with a C++ compiler (e.g. use of malloc will need casting).
If on, the other hand, you have a library or some other code that isn't part of your project, then you do need to make sure the headers are marked as extern "C", otherwise C++ naming convention for the compiled names of functions will apply, which won't match the naming convention used by the C compiler.
There are two options here, either you edit the header file itself, adding
#ifdef __cplusplus
extern "C" {
#endif
... original content of headerfile goes here.
#ifdef __cplusplus
}
#endif
Or, if you haven't got the possibility to edit those headers, you can use this form:
#ifdef __cplusplus
extern "C" {
#endif
#include <c_header.h>
#ifdef __cplusplus
}
#endif
Yes, but you need to tell the C++ compiler that the declarations from the header are C:
extern "C" {
#include "c-header.h"
}
Many C headers have these included already, wrapped in #if defined __cplusplus. That is arguably a bit weird (C++ syntax in a C header) but it's often done for convenience.
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 know OpenCL has a C++ binder, but I use a third party library which is currently only working with CL.h. I want to write my program in C++. Is it safe to include cl.h in a C++ program and work with that in C style?
I saw some examples of including cl.h in C++ and they seem to be working. However, I don't know for sure. Is there any specific situation that may cause problems?
Yes. It is a C/C++ header with proper "extern "C" " guards.
http://www.khronos.org/registry/cl/api/1.0/cl.h
If it's a C header, you can wrap it in extern "C" directives:
extern "C"
{
#include "CL.h"
}
this tells the linker not to apply name mangling when looking for the functions declared in the header.