If I use gcc as a driver, call all my source files .c and .h, can I be sure that I wont have any C++ source in my sources? Are there any gcc parameters to make sure that he throws errors in case any c++ is encountered in the source?
I am especially paranoid about include files, because I am not 100% sure whether I include C headers or C++ headers.
Some examples I ran into in the past:
trying to use the type bool
using wrong includes cstdio vs. stdio.h
trouble with the struct keyword
I just want to make 100% sure that my source is only C and has no C++ in it.
GCC will figure out itself whether it's a C or a C++ source code. How? It scans the file extension the file you passed has.
These are the extensions accepted.
In case you want to force a specific language, use the -x flag (documented in the link above). Furthermore, you may check whether the macro __cplusplus is defined.
Related
I have been thinking this problem for a while but still no idea about it, if my project is mainly cpp file, should a c file name as .c, or should be named as .cpp to consistent with other .cpp file?
I just list some advantage and disadvantage (in my current knowledge) of using .c (I don't know if the following idea is correct):
advantage of .c:
fast to know it does not contain c++ content (e.g.:class,std::string)
easy to separate from .cpp file by searching name
disadvantage of .c:
not consistent with other files (because other files mostly .cpp)
may need to rename it as .cpp if I want to change the function as using oop or want to add some oop features into it
some scripts or files may need to add *.c as file input if the original version only handles *.cpp, (e.g.: need to add *.c in Android.mk in android jni)
Also I don't know if compiler handles .c and .cpp in different way,also don't know if it affects other behaviour (e.g.:performance,platform or compiler specific issues...), is anyone have idea about it?
Depends what you mean by "C" code.
Are you going to compile it with a C compiler?
Call it file.c
Or do you just mean "C-like" C++ code? C++ code that, at time of writing, happens to also be valid C?
Call it file.cpp
Rule of thumb - name it according to which compiler you intend to use for it. This keeps your makefiles nice and simple.
So if your "C code" is C++ code that could be compiled as valid C but that's not what you are doing, then name it *.cpp and let your makefile invoke the C++ compiler on it.
If your code is actual C, to be compiled with a C compiler, then name it *.c - and remember the (appropriately-#ifdefed) extern "C" in the header file so that C++ built against it can link successfully.
C++ fully supports c code. So the compiler would be just fine with c code in a .cpp file.
And like Quentin mentioned above. If your c code is never used in a c only project I would leave it in an cpp file.
I have an third party source file and corresponding header (containing the declarations and include directives for GSL etc) which are written in C. I am trying to build an R package around these source files, basically making a wrappers for the functions using Rcpp. Problem is that these files contain restrict qualifier which is not part of the C++ standard, so R CMD INSTALL cannot compile the package. It does use C compiler for .c file, but want's to compile .h file with C++ compiler and it fails. it fails when it finds restrict in header file (which is included in .cpp file).
I am not that familiar with C and compiler things and Rcpp etc, so I am not sure what would be a best approach here?
Easiest thing would probably be to remove the restrict keyword. This is what I have currently done (I am suprised that R CMD INSTALL works when I remove restrict from header file but leave them to .c file). But I rather not alter the .c and .h files as they are also used in non-R environment by others (executable and in Python) and it would be nice to have identical files for all projects.
I also tried to define empty keyword restrict so that it would just "remove" restrict from function definitions if the compilation was done in C++ compiler, but I couldn't get that work. I read about similar approach somewhere but apparently it doesn't work that way.
Would it work if I could somehow tell the compiler (via Makevars or something?) that the particular .h file should be compiled with C compiler? Or is there going to be problems with C++ function calling those functions?
Or will the whole keyword even matter in terms of performance if those functions are called from R via C++ wrapper?
One thing would be to just ditch the Rcpp and use .C instead of .Call from R, but as the performance is a key here, that doesn't feel a good option, as I understand that .Call is faster (and more reliable).
Note that eventually this package could find it's way to CRAN, so the solution should be fairly portable. There seems to be some C++ compiler specific keywords for restrict but I guess those are not an option due to the portability.
It sounds like you are making a .cpp file which does #include <x.h> where x.h is a C header which uses restrict. If that's true, I think you can modify your .cpp file to do this:
#define restrict // nothing
extern "C"
{
#include <x.h>
}
Then compilation of your C++ code will not see the restrict keyword, and also I have wrapped the header in extern "C" because if the header itself doesn't do that internally, you need to, in order that your C++ compiler will not apply C++ "name mangling" to the functions declared inside.
I'm trying to have Cmake check if the file cxxabi.h is available. This file is from the c++ standard library, at least with g++. My current cmake commands look like this:
include(CheckIncludeFiles)
...
check_include_files(cxxabi.h HAVE_CXXABI)
if(HAVE_CXXABI)
...
else(HAVE_CXXABI)
...
endif(HAVE_CXXABI)
When this is executed, I get:
-- Looking for include files HAVE_CXXABI
-- Looking for include files HAVE_CXXABI - not found.
Although the file is available in /usr/include/c++/4.6.4/ and can properly be found by g++ when I compile a c++ code.
I suspect the macro check_include_files uses the C compiler instead of the C++ one to compile a small program that includes the required file, which of course fails since cxxabi.h is a C++ file.
Any idea how to solve that? (i.e. making the macro use the C++ compiler instead of the C one)
As edited in my original question:
Problem solved. There is a different macro for C++ headers, check_include_file_cxx, located in CheckIncludeFileCXX.
There exists another problem with CHECK_INCLUDE_FILES that I recently discovered with MinGW. The file tested was "ddk/ntapi.h". In the CMakeErr.log for this header I got a multiply messages like "DWORD - does not name a type" and so on for all MS types used in this header. Because of this reason the compilation fails and a requested header appears as "not found", whereas it is not true.
This happens because CheckIncludeFile.cxx contains only the requested header, and some headers in MinGW (and probably in the other APIs) does not include in its body all the list of required headers to be compiled in a standalone program that CMake creates.
The solution for this problem is to add absent basic includes into the CMAKE_REQURED_FLAGS, or as a third variable of CHECK_INCLUDE_FILE_CXX:
CHECK_INCLUDE_FILE_CXX("ddk/ntapi.h" VAR "-include windows.h")
I have an Xcode 4.2 project which includes a target that cross-compiles for windows. I use custom build rules for C source files and C++ source files in that target, invoking i386-pc-mingw32-g++ via a custom script. For some reason, Xcode runs the custom script I have specified as being for C source files, even when compiling files with a .cpp extension. Why might this be? How can I get Xcode 4.2 to run the "C++ source files" script for my .cpp files?
I also have .c files in this project, and am hoping to use -std=c++11 flag when compiling c++ files to enable some c++11 features. If I compile the .c files with this flag, I end up with weird scoping issues on constants included from math.h that I have yet to really try and understand - I am hoping I can just get Xcode to run the correct script for my .cpp files.
Any ideas?
Update: I've been able to get Xcode to run the correct scripts. To do this, I had to change the Process drop-down menu selections from "C source files" and "C++ source files" both to "Source files with names matching:" and then manually enter *.c and *.cpp in the provided text field. Now I have to figure out why I'm getting an M_PI was not declared in this scope error message where I wasn't before - maybe a different version of math.h is being used with the -std=c++11 flag which either doesn't include the M_PI constant or provides it under a different namespace?
Update: Continuing to work on this - it appears the M_PI value I was using from math.h is actually a macro which is only #define'd if __STRICT_ANSI__ has not been defined. Apparently switching to c++11 by using the -std=c++11 compiler flag has caused this __STRICT_ANSI__ macro to be defined, and thus the M_PI macro I was previously using isn't there. I suppose it's better to just define my own pi constants than to mess with the declaration of this __STRICT_ANSI__ macro, but I'll probably dig into that a bit just to clarify why it is being declared now that I'm using the c++11 flag.
Update: I found this post How can I make C++0x and __STRICT_ANSI__ get along?, which just suggests undefining the 'STRICT_ANSI' macro right after the '-std=c++11' flag (or rather, the equivalent '-std=c++0x' flag. While this seems sketchy, no one has posted encountering any problems because of it and it appears to work just fine for me as well in this case. Gcc documentation on this macro is located here: http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html, with the following relevant statement:
The macro STRICT_ANSI is predefined when the -ansi option is used. Some header files may notice this macro and refrain from declaring certain functions or defining certain macros that the ISO standard doesn't call for; this is to avoid interfering with any programs that might use these names for other things.
Still not sure why the '-std=c++11' flag causes this to be defined when it isn't by default (which would be '-std=c++98', apparently).
If you want C++11 support without ANSI mode, use -std=gnu++11 instead of std=c++11.
Question: what is the best way to convert a .c/.h based project (which is forcefully compiled as C++ via the makefiles) to a .cpp/.hpp based project?
Obviously, this is a triple-step process. The first would be to rename everything with *.c at the end to *.cpp; the second would be to rename everything with *.h at the end to *.hpp. What I'm getting caught up on is the third step- somehow building a list of what the files /were/ named (ie, myfile.c), then iterating through every single affected file and replacing every instance of the old filename with the new (myfile.c -> myfile.cpp). Obviously this would have to be done so the source files can still find everything that they need.
The source code in question consists of around 2700 individual source files.
The reason why I'm doing this is mostly because I'm porting said software package to Mac OS X, and that involves Xcode. Things are getting bloody messy trying to keep track of precisely what is C, C++, and the associated headers for either (then overriding the compiler for C++ compilation). It would be much simpler if everything C++ was *.cpp (with the associated headers being *.hpp), since then I can just leave Xcode at the default compiler setting as per the file extension and everything should work without any fancy intervention on my end.
I should probably also note that I know precisely what files need to be converted, because they already compile properly and in a sane fashion if I'm overriding Xcode to compile as C++. That's not a problem- my issue is trying to figure out how to batch rename everything then run through all the files and update the #includes.
Thank you in advance!
-Keven Tipping
You don't need to mess with the headers. filename.h is a perfectly good name for a C++ header.
If you're not using the old makefile, but creating a new XCode project, then you have only one step:
Rename *.c to *.cpp
If the makefile was written right (using rule patterns and not specific per-file rules), there shouldn't be any changes needed there either.
There's no reason to rename those C language header and source files to C++ and there are many reasons not to. Just three of the many:
Reason #1: C and C++ are diverging, different languages. Force-compiling a C file as if it were C++ risks introducing a bug.
Reason #2: Xcode can handle C, C++, and C and C++ mixed together.
Reason #3: C++ can easily call C routines. All you need to do is wrap the declarations of those C functions inside an extern "C" { /* C declarations here */ } construct.