I have been working with qt creator and recently tried to change the compiler from gcc to clang. Since I don't get any info (or can't see it) on whether this worked (I'm struggling to understand the interface) I wanted to ask if there's a way for my c++ code to print out the compiler under which it's being compiled.
Compilers set certain #defines to help out with things like this.
In your case,
#ifdef __GNUC__ //GCC
//do whatever GCC-specific stuff you need to do here
#endif
#ifdef __clang__ //clang
//do whatever clang-specific stuff you need to do here
#endif
This page on SourceForge shows a list of such compiler-specific #define values.
EDIT: as pointed out in the comments, clang sets __GNUC__, and possibly __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. You might be better off using a double test to make sure clang isn't misleading you:
#if defined(__GNUC__) && !defined(__clang__)
//do whatever GCC-specific stuff you need to do here
#endif
Use the informational macros of boost.
#include <boost/config.hpp>
#ifdef BOOST_CLANG
printf("Successfully changed to clang\n");
#endif
Related
Is it possible to execute emcc (from emscripten) on a clang compiled executable ?
I tried but the result is:
ERROR root: pdfium_test: Input file has an unknown suffix, don't know what to do with it!
I try that because I'm not able to find a solution to compile PDFium project with emcc, but with clang everything is fine.
The reason is:
Emscripten is a cross-compiler, and therefore the OS-specific macros
of the host system should all be undefined when building C/C++ code.
If you look at tools/shared.py, Emscripten gives special attention to
-U all host-specific flags that Clang may automatically try to add in.
But there is lots of Platform specific code in PDFium, so I get:
#error Sorry, can not figure out target OS. Please specify _FX_OS_ macro.
This macro is defined if the __linux__ macro (for example) is defined, here is the code snippet:
#ifndef _FX_OS_
#if defined(__ANDROID__)
#define _FX_OS_ _FX_ANDROID_
#define _FXM_PLATFORM_ _FXM_PLATFORM_ANDROID_
#elif defined(_WIN32)
#define _FX_OS_ _FX_WIN32_DESKTOP_
#define _FXM_PLATFORM_ _FXM_PLATFORM_WINDOWS_
#elif defined(_WIN64)
#define _FX_OS_ _FX_WIN64_DESKTOP_
#define _FXM_PLATFORM_ _FXM_PLATFORM_WINDOWS_
#elif defined(__linux__)
#define _FX_OS_ _FX_LINUX_DESKTOP_
#define _FXM_PLATFORM_ _FXM_PLATFORM_LINUX_
#elif defined(__APPLE__)
#define _FX_OS_ _FX_MACOSX_
#define _FXM_PLATFORM_ _FXM_PLATFORM_APPLE_
#endif
#endif // _FX_OS_
#if !defined(_FX_OS_) || _FX_OS_ == 0
#error Sorry, can not figure out target OS. Please specify _FX_OS_ macro.
#endif
So, I tried to define manually the __linux__ macro with:
emmake make -j5 BUILDTYPE=Release __linux__=1
... but same error. Maybe it's not the good way ?
Thank you in advance.
EDIT: The answer of JF Bastien helps me a lot. But now I've this build error and I've any idea of what to do. If someone have an idea...
clang-3.7: warning: argument unused during compilation: '-msse2'
clang-3.7: warning: argument unused during compilation: '-mmmx'
error: unknown FP unit 'sse'
EDIT 2: Solution for above problem: remove "-msse2, -mmmx and -mfpmath" flags from v8/build/toolchain.gypi
Porting to Emscripten is the same as porting to any other platform: you have to use that's platform's own platform-specific headers. Some will have nice equivalents, and some won't.
In most cases you'll need to find these chains of platform-specific #if defined(...) and add an #elif defined(__EMSCRIPTEN__), and do the right thing there. That's more complicated than it sounds: you can't do inline assembly, you can't rely on (most) platform-specific headers, ... But in some cases it's easy.
Emscripten has examples which do this, and has a porting guide.
For PDFium in particular, you'll have to avoid all the platform-specific font rendering, any threading-related things, and the sandboxing (security shouldn't be as big of an issue since JavaScript itself is a sandbox). You'll also have to figure out how to do file I/O, and probably want to disable all networking code.
Or you could use other ports of PDFium to Emscripten.
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)
In a C++ project documented with Doxygen, I have marked some functions as \deprecated in the Doxygen comments. Is there any way to use these comments (with Doxygen or another tool) in order to detect that another non-deprecated function is calling a deprecated one ? (The project is pretty big and going through all the classes would take a lot of time).
Thanks
If you are using GCC or clang to compile your code you could manually annotate functions.
__attribute__((__deprecated__))
void dep_fun() { }
Then calling dep_fun anywhere in your code will emit a diagnostic message.
If you placed doxygen's \deprecated annotation consistently you should be able to update the code automatically with tools like sed.
Building on Benjamins answer:
Some useful compiler directives:
#ifdef _MSC_VER
#define DEPRECATED __declspec(deprecated)
#elif defined(__GNUC__) | defined(__clang__)
#define DEPRECATED __attribute__((__deprecated__))
#else
#define DEPRECATED
#endif
//usage:
DEPRECATED void foo(int bar);
(warning: untested under clang and msc, only tested on GNUC.)
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.