I'm trying to determine if C++0x features are available when compiling. Is there a common preprocessor macro? I'm using Visual Studio 2010's compiler and Intel's compiler.
The macro __cplusplus will have a value greater than 199711L.
That said, not all compilers will fill this value out. Better to use Roger's solution.
The usual way to do this is determine it in the build system, and pass "configuration macros", commonly named HAS_*, when compiling. For example: compiler -DHAS_LAMBDA source.cpp.
If you can determine this from compiler version macro, then you can define these macros in a configuration header which checks that; however, you won't be able to do this for anything controlled by a command-line option. Your build system does know what options you specify, however, and can use that info.
See boost.config for a real example and lots of details about specific compilers, versions, and features.
We've had similar problems with nullptr and auto_ptr. Here's what we're trying to use until somehing is standardized:
#include <cstddef>
...
// GCC: compile with -std=c++0x
#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || (__GNUC__ >= 5))
# define HACK_GCC_ITS_CPP0X 1
#endif
#if defined(nullptr_t) || (__cplusplus > 199711L) || defined(HACK_GCC_ITS_CPP0X)
# include <memory>
using std::unique_ptr;
# define THE_AUTO_PTR unique_ptr
#else
# include <memory>
using std::auto_ptr;
# define THE_AUTO_PTR auto_ptr
#endif
It works well on GCC and Microsoft's Visual Studio. By the way, nullptr is a keyword and can't be tested - hence the reason for the nullptr_t test.
Related
Various modern C/C++ compilers include one or both of __func__ / __FUNCTION__ for purposes of logging the currently executing function. MSVC++ also includes __FUNCSIG__ and GCC __PRETTY_FUNCTION__ as compiler-specific enhanced flavors of this functionality.
GCC defines these as variables rather than macros, however, so it isn't possible to test for their presence via a #ifdef preprocessor directive.
I'm working with a codebase that must work with C++98 and C++11 flavors of MSVC++ and GCC, and the logging facility that someone wrote erroneously tries to test for __FUNCTION__ if __FUNCSIG__ is not available. This check always returns false, rendering function logging support non-operational.
Question: Is there a good macro out there that makes a sufficient-for-my-use-cases guess at which (if any) of these features should be present, possibly by sniffing out compiler versions?
T.C. supplied this answer first, as a comment under my question, and I ended up basing my solution on it:
The header <boost/current_function.hpp> in Boost.Assert implements a BOOST_CURRENT_FUNCTION macro that attempts to map to a suitable "current function" facility provided by the compiler.
Documentation is here:
http://www.boost.org/doc/libs/1_66_0/libs/assert/doc/html/assert.html#current_function_macro_boost_current_function_hpp
And here is a concise reproduction of the macro for reference:
#if defined( BOOST_DISABLE_CURRENT_FUNCTION )
# define BOOST_CURRENT_FUNCTION "(unknown)"
#elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__DMC__) && (__DMC__ >= 0x810)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
# define BOOST_CURRENT_FUNCTION __FUNCTION__
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
# define BOOST_CURRENT_FUNCTION __FUNC__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define BOOST_CURRENT_FUNCTION __func__
#elif defined(__cplusplus) && (__cplusplus >= 201103)
# define BOOST_CURRENT_FUNCTION __func__
#else
# define BOOST_CURRENT_FUNCTION "(unknown)"
#endif
I ended up modifying the codebase I was working with to use the Boost macro when available, and to fall back to a reasonable subset of the Boost checks otherwise (GCC > MSVC++ > C++11).
__func__ was specified in C99 (not C++) and gcc has provided __FUNCTION__ and __PRETTY_FUNCTION__ for quite a while. However, none are actually macros, so can't be used as such. Among other things, that means you can't test for them using #ifdef.
To test if you are compiling as C++, and to what standard, use __cplusplus which is specified in the C++ standard, and expands to values 199711L (before C++11), 201103L (C++11), 201402L (C++14), and 201703L (C++17). The values correspond to the dates (year and month) when the standardisation committee approved the standard (e.g. 201703L means that C++17 was approved in March 2017). Note this is macro is only defined when compiling C++, not C.
Beyond that, to use features specific to a compiler, you need to test for the compiler that supports the features you want, not the feature itself (although some compilers/preprocessors do allow testing for particular language features, that's patchy in practice).
gcc and g++ (and other compilers that claim to support gnu C dialects) provide a number of specific macros, so you can check for them including
__GNUC__, defined for the GNU C compiler (can be tested using #ifdef). For gcc version x.y.z, __GNUC__ expands to the value x;
__GNUC_MINOR__, defined for the GNU C compiler (can be tested using #ifdef). For gcc version x.y.z, __GNUC_MINOR__ expands to the value y;
__GNUC_PATCH_LEVEL__, defined for the GNU C compiler (can be tested using #ifdef). For gcc version x.y.z, __GNUC_PATCHLEVEL__ expands to the value z;
__GNUG__ - defined for the g++ compiler.
An example of how you might use the gnu-specific macros is
#ifdef __GNUG__
/* Assume all versions of gcc that you use support __FUNCTION__ */
/* can use gcc's __FUNCTION__ here */
#endif
I don't know offhand which g++ versions started supporting __FUNCTION__ and __PRETTY_FUNCTION__, but if you want to test for particular version of the compiler, it's easy. For example, to test for g++ 3.2.0 or better
#ifdef __GNUG__
// test for g++ 3.2.0 or better
#if __GNUC__ > 3 || \
(__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
(__GNUC_MINOR__ == 2 && \
__GNUC_PATCHLEVEL__ > 0))
// use features not introduced before g++ 3.2.0
#endif
#endif
For MSVC++, compiler-specific macros for a similar purpose include _MSC_VER which expands to an encoding of the major and minor versions. For example, under MSVC++ version 17.00.51106.1, _MSC_VER expands to 1700. You can find others on MSDN.
I am working on a project that has been built with both gcc and msvc so far. We recently started building with clang as well.
There are some parts in the code, where platform-specific things are done:
#ifndef _WIN32
// ignore this in msvc
#endif
Since gcc has previously been the only non-windows build, this was equivalent to saying "do this only for gcc". But now it means "do this only for gcc and clang".
However there are still situations, where I would like to handle something specifically for gcc, and not for clang. Is there a simple and robust way to detect gcc, i.e.
#ifdef ???
// do this *only* for gcc
#endif
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
These macros are defined by all GNU compilers that use the C preprocessor: C, C++, Objective-C and Fortran. Their values are the major version, minor version, and patch level of the compiler, as integer constants. For example, GCC 3.2.1 will define __GNUC__ to 3, __GNUC_MINOR__ to 2, and __GNUC_PATCHLEVEL__ to 1. These macros are also defined if you invoke the preprocessor directly.
Also:
__GNUG__
The GNU C++ compiler defines this. Testing it is equivalent to testing (__GNUC__ && __cplusplus).
Source
Apparently, clang uses them too. However it also defines:
__clang__
__clang_major__
__clang_minor__
__clang_patchlevel__
So you can do:
#ifdef __GNUC__
#ifndef __clang__
...
Or even better (note the order):
#if defined(__clang__)
....
#elif defined(__GNUC__) || defined(__GNUG__)
....
#elif defined(_MSC_VER)
....
I use this define:
#define GCC_COMPILER (defined(__GNUC__) && !defined(__clang__))
And test with it:
#if GCC_COMPILER
...
#endif
With Boost, this becomes very simple:
#include <boost/predef.h>
#if BOOST_COMP_GNUC
// do this *only* for gcc
#endif
See also the Using the predefs section of the boost documentation.
(credit to rubenvb who mentioned this in a comment, to Alberto M for adding the include, and to Frederik Aalund for correcting #ifdef to #if)
I have some code that requires a certain gcc compiler option (otherwise it won't compile). Of course, I can make sure in the makefile that for this particular source file the required option is set. However, it would much more helpful, if this option could be set for the respective compilation unit (or part of it) from within the source_file.cpp.
I know that warning messages can be switched on or off using #pragma GCC diagnostic, but what about the -fsomething type of options? I take it from this question that this is impossible.
But perhaps there is at least a way to check from within the code whether a certain -f option is on or not?
Note I'm not interested in finding the compiler flags from the binary, as was asked previously, nor from the command line.
In my experience, no. This is not the way you go about this. Instead, you put compiler/platform/OS specific code in your source, and wrap it with the appropriate ifdef statements. These include:
#ifdef __GNUC__
/*code for GNU C compiler */
#elif _MSC_VER
/*usually has the version number in _MSC_VER*/
/*code specific to MSVC compiler*/
#elif __BORLANDC__
/*code specific to borland compilers*/
#elif __MINGW32__
/*code specific to mingw compilers*/
#endif
Within this, you can have version-specific requirements and code:
#ifdef __GNUC__
# include <features.h>
# if __GNUC_PREREQ(4,0)
// If gcc_version >= 4.0
# elif __GNUC_PREREQ(3,2)
// If gcc_version >= 3.2
# else
// Else
# endif
#else
// If not gcc
#endif
From there, you have your makefile pass the appropriate compiler flags based on the compiler type, version, etc, and you're all set.
You can try using some #pragma. See GCC diagnostic pragmas & GCC function specific pragmas.
Otherwise, develop your GCC plugin or your MELT extension and have it provide a pragma which sets the appropriate variables or compiler state inside GCC (actually cc1plus)
I'm interested in creating a macro for eliminating the unused variable warning.
This question describes a way to suppress the unused parameter warning by writing a macro inside the function code:
Universally compiler independent way of implementing an UNUSED macro in C/C++
But I'm interested in a macro that can be used in the function signature:
void callback(int UNUSED(some_useless_stuff)) {}
This is what I dug out using Google (source)
#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*#unused#*/ x
#elif defined(__cplusplus)
# define UNUSED(x)
#else
# define UNUSED(x) x
#endif
Can this be further expanded for other compilers?
Edit: For those who can't understand how tagging works: I want a solution for both C and C++. That is why this question is tagged both C and C++ and that is why a C++ only solution is not acceptable.
The way I do it is like this:
#define UNUSED(x) (void)(x)
void foo(const int i) {
UNUSED(i);
}
I've not had a problem with that in Visual Studio, Intel, gcc and clang.
The other option is to just comment out the parameter:
void foo(const int /*i*/) {
// When we need to use `i` we can just uncomment it.
}
Just one small thing, better using __attribute__((__unused__)) as __attribute__((unused)), because unused could be somewhere defined as macro, personally I had a few issues with this situation.
But the trick I'm using is, which I found more readable is:
#define UNUSED(x) (void)x;
It works however only for the variables, and arguments of the methods, but not for the function itself.
After testing and following the comments, the original version mentioned in the question turned out to be good enough.
Using: #define UNUSED(x) __pragma(warning(suppress:4100)) x (mentioned in comments), might be necessary for compiling C on MSVC, but that's such a weird combination, that I didn't include it in the end.
Across many compilers I have used the following, excluding support for lint.
#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
# define PGM_GNUC_UNUSED __attribute__((__unused__))
#else
# define PGM_GNUC_UNUSED
#endif
Tested compilers: GCC, Clang, EKOPath, Intel C Compiler / Composer XE, MinGW32 on Cygwin / Linux / MSYS, MinGW-w64 on Cygwin / Linux, Sun ONE Studio / Oracle Solaris Studio, Visual Studio 2008 / 2010.
Example usage:
pgm_tsc_init (
PGM_GNUC_UNUSED pgm_error_t** error
)
{
...
}
PGM is the standard prefix for this C based project. GNUC is the convention from GLib for this attribute.
I think one compile warns about __attribute__ in certain circumstances but certainly no error.
I am not able to understand the following statement from the file limits.h. What is the use of this statement and what does it accomplishes?
/* If we are not using GNU CC we have to define all the symbols ourself.
Otherwise use gcc's definitions (see below). */
#if !defined __GNUC__ || __GNUC__ < 2
It checks if your program is compiled by some other compiler than GCC, or some very old GCC version.
It checks whether you are not using a Gcc compiler Version 2 or Gcc some other versions.
using this pre-processor macro we can some portable codes.