I would like to detect whether a .cu file is compiled with C++11 support enabled. At the moment i have the following:
#if CUDART_VERSION < 7050
#define C11SUPPORTED 0
#else
#define C11SUPPORTED 1
#endif
However this is not working because even though C++11 is supported, it is not enabled unless -std=c++11 switch is passed. Is there perhaps something else defined when -std=c++11 is passed?
Update
nvcc --compiler-options -dM -E -x cu - < /dev/null | grep "__cplus"
returns
#define __cplusplus 201402L
I am using NVCC version V9.1.85. Will checking __cplusplus work, even for older NVCC versions?
If nvcc is standard conforming, you should be able to check the value of __cplusplus like this
#if __cplusplus >= 201103
#define C11SUPPORTED 1
#else
#define C11SUPPORTED 0
#endif
Checking the value of __cplusplus should work with any C++ compiler since at least C++98.
Related
I'm trying to compile a program on Windows using MingW (msys2) and it fails with the j0 function. On Linux it compiles no problem. It seems to hate when I use the -std=c++11 flag on the compiler. How can I get this to compile properly and with the -std=c++11 flag on?
Sample code:
#include <cmath>
int main( int argc, char *argv[] )
{
float test = j0( 5 );
}
Output
$ g++ -std=c++11 test.cpp -o test
test.cpp: In function 'int main(int, char**)':
test.cpp:6:21: error: 'j0' was not declared in this scope
float test = j0( 5 );
Apparently, MinGW defines the Bessel functions only when __STRICT_ANSI__ is not defined, and it is defined when -std=c++11 is specified. I was able to get your code to compile in MinGW by adding #undef __STRICT_ANSI__ at the top of the file. See https://sourceforge.net/p/mingw-w64/feature-requests/68/
You might also try -std=gnu++11 instead. See https://stackoverflow.com/a/19667112/10077
I have some preprocessor code like this:
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#if GCC_VERSION < 40503
#error Your compiler is outdated.
#error You need at least gcc 4.5.3 for this library.
#error You have: GCC_VERSION
#error You have: STR(GCC_VERSION)
#endif
However both ways I tried to output the current compiler version fail. According to the documentation this is because
Neither ‘#error’ nor ‘#warning’ macro-expands its argument. Internal whitespace sequences are each replaced with a single space. The line must consist of complete tokens. It is wisest to make the argument of these directives be a single string constant; this avoids problems with apostrophes and the like.
How can I output the compiler version with the error message anyway? Is there any preprocessor magic that allows me to achieve this?
The classic "solution" to this problem is to manage to generate an error which includes the desired message. For example:
#define S(x) #x
#define STR(x) S(x)
#if GCC_VERSION < 40503
#error Outdated compiler: you need at least gcc 4.5.3 for this library.
#define above_message_indicates_installed_gcc_version STR(Installed GCC version: GCC_VERSION)
#include above_message_indicates_installed_gcc_version
#endif
While that does provide some information, it is still subject to misinterpretation; personally, I think letting the developer know the minimum version required is sufficient.
Note: The above snippet assumes that GCC_VERSION has already been defined, which I assume must have been done before the snippet in the OP. But beware: since the preprocessor does text substitution, not arithmetic evaluation (except in #if directives), you need to assemble GCC_VERSION in a different form for the error message If you want to try this, you could use the following:
#define GCC_VERSION (__GNUC_PATCHLEVEL__ + 100 * (__GNUC_MINOR__ + 100 * __GNUC__))
#define S_(x) #x
#define STR(x) S_(x)
#if GCC_VERSION < 40503
#undef GCC_VERSION
#define GCC_VERSION __GNUC__.__GNUC_MINOR__.__GNUC_PATCHLEVEL__
#error Outdated compiler: you need at least gcc 4.5.3 for this library.
#define above_message_indicates_installed_gcc_version STR(Installed GCC version: GCC_VERSION)
#include above_message_indicates_installed_gcc_version
#endif
See it on gcc.godbolt
If #error does not expand its arguments, I would just take a pragmatic approach:
#if GCC_VERSION < 40503
#error Outdated compiler < 4.5.3, run 'gcc --version' to get version.
#endif
The only other possibility I can think of is to preprocess the file with your own preprocessor, to replace all occurences of (for example) xyzzy_GCC_VERSION_plugh with something extracted from gcc --version.
That's going to be a lot of effort and maintenance load to do what probably isn't necessary anyway.
But, if you really want to do it, you could use something like:
actual=$(echo "GCC_VERSION" | gcc -E - | tail -1)
sed "s/xyzzy_GCC_VERSION_plugh/$actual/g" file1.c >file1_morphed.c
gcc -c -o file1.o file1_morphed.c
and your file1.c would contain at the top somewhere:
#if GCC_VERSION < 40503
#error Outdated compiler xyzzy_GCC_VERSION_plugh < 4.5.3
#endif
But, as i said, that's a fair bit of work for not much benefit. My advice is just to tell the person using your library how to get the compiler version themselves. They are developers after all, I'd expect them to be able to handle an instruction like that.
Combining the proposal of paxdiablo and ideas for static compile time assertions I settled for the following solution.
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#define ERROR_MESSAGE(major, minor, patchlevel) compiler_version__GCC_ ## major ## _ ## minor ## _ ## patchlevel ## __ ;
#define OUTDATED_COMPILER_ERROR(major, minor, patchlevel) ERROR_MESSAGE(major, minor, patchlevel)
#if GCC_VERSION < 40503
#error Outdated compiler version < 4.5.3
#error Absolute minimum recommended version is avr-gcc 4.5.3.
#error Use 'avr-gcc --version' from the command line to verify your compiler version.
#error Arduino 1.0.0 - 1.0.6 ship with outdated compilers.
#error Arduino 1.5.8 (avr-gcc 4.8.1) and above are recommended.
OUTDATED_COMPILER_ERROR(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#endif
I've got an Xcode project that I'm migrating to use with clang's option -stdlib libc++, to enable C++11 support. Some of my source files need to know which library is being used, for instance so that I do things like this:
#ifdef HAVE_CPP11_LIB_SUPPORT
#include <memory>
#else
#include <tr1/memory>
#endif
#ifdef HAVE_CPP11_LIB_SUPPORT
vector.emplace_back(newValue);
#else
vector.push_back(newValue);
#endif
I'm having trouble though finding the preprocessor macros (if indeed there are any) that are set for this option. I've tried dumping the outputs of clang with:
clang -x c++ -std=c++11 -stdlib=libc++ -dM -E - < /dev/null
to compare with:
clang -x c++ -std=c++11 -stdlib=libstdc++ -dM -E - < /dev/null
but this gives the same results. Note that I don't want to switch on whether we're using the c++11 language setting, but whether we're using the c++11 library. Is there any reliable way of detecting this in the code?
I don't know of any sure way that is guaranteed to be portable, but this is what I use for now:
// libc++ detected: _LIBCPP_VERSION
// libstdc++ detected: __GLIBCXX__
#if defined(__clang__)
# if __has_include(<__config>) // defines _LIBCPP_VERSION
# include <__config>
# elif __has_include(<bits/c++config.h>) // defines __GLIBCXX__
# include <bits/c++config.h>
# else
# include <ios>
# endif
#elif defined(__GNUC__) // gcc does not have __has_include
# include <ios> // ios should include the c++config.h which defines __GLIBCXX__
#endif
It's not great, but works for me for now.
libc++ defines _LIBCPP_VERSION and stdc++ defines __GLIBCXX__ which is nice, but unfortunately these macros are not defined by the compiler. Instead, they're defined in a non-standard header file, and you cannot test their definition unless that header has been included.
Note: Apparently stdc++ defined __GLIBCPP__ in older versions instead. Since you require c++11, this isn't going to be a problem.
Clang (Edit: Standard since C++17) has a nice feature __has_include which can be used to test for these but if neither header is found, the macro falls back to just including a standard header which hopefully uses the internal header under the hood. I have <ios> here, but the choice of standard header to include is up to you. You can look for headers that include the internal header with something like (this is for gcc on linux):
grep -Rl '#include <bits/c++config.h>' /usr/include/c++
Pick any header that you're likely to use in the project anyway.
Since this isn't guaranteed to work for any given past or future compiler/standard library version, I wouldn't rely on these defines for anything but optional features like:
#ifdef __GLIBCXX__
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
#endif
#ifdef __has_include
# if __has_include(<ciso646>)
# include <ciso646>
# if defined(_LIBCPP_VERSION)
# define USING_LIBCPP 1
# endif
# endif
#endif
#if !USING_LIBCPP
# define USING_LIBSTDCXX 1
#endif
If you're writing these kinds of checks I suggest you choose a compiler/library version and require that or newer. It makes no sense to half-use C++11 library features. On Mac OS X, just require compilation with clang++ -stdlib=libc++.
I use next code:
#include <cstddef> // for __GLIBCXX__
#ifdef __GLIBCXX__
# include <tr1/memory>
#else
# include <memory>
#endif
source
I'm compiling on the command line with avr-gcc
One of the includes I'm using has the following lines:
#ifndef F_CPU
#warning No CPU speed specified - assuming Axon is running at 16MHz
#define F_CPU 16000000
#endif
#if F_CPU != 16000000
#warning "AxonII normally runs at 16MHz but you have defined a different value"
#endif
When I run make I get:
In file included from main.c:7:
../webbotavrclib/sys/axon2.h:86:11: error: operator '!=' has no left operand
Line 86 is #if F_CPU != 16000000 above. I'm not sure why I'm getting the error though.
Such message can be produced, for example, for the following compilation:
$ gcc main.c -DF_CPU=
main.c:6:11: error: operator '!=' has no left operand
Note that F_CPU is defined, but is not anything for != to use.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Running the GCC preprocessor
Is there a GCC option to make the GCC preprocessor generate C source code but filter out irrelevant source code?
For example, a C file has #define switch to define for many different platforms. I'm only intersted in one platform, so I want the C preprocessor to filter out unrelated code. Does GCC support this?
Use gcc -E to only run the preprocessor part, e.g. give a file in.c
#if 0
0;
#endif
#if 1
1;
#endif
running
$ gcc -E in.c -o in.i
yields a file in.i
# 1 "in.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "in.cpp"
1;
i.e. the parts behind the #if 0 got removed. If you would have #include'd files they would have been pasted too though, so I am not sure how much help this is.
It sounds like you actually want unifdef, not the GCC preprocessor.
Yes - almost certainly your compiler provides certain default definitions in the environment that you can use to turn code on and off for different systems. __GNUC__ is a good one for GCC. For example:
#ifdef __GNUC__
#define SOME_VALUE 12
#else
#define SOME_VALUE 14
#endif
If you compile that block with GCC, SOME_VALUE will be 12, and if you compile with MSVC, for example, SOME_VALUE will be 14. A list of platform specific definitions is available at this question.
You probably can use:
gcc -CC -P -Uswitch -undef -nostdinc -fdirectives-only -dDI -E
With switch the #define you know will be undefined.