#elseif vs #elif (C/C++ preprocessor) - c++

I have found that writing
#ifdef ...
#elseif defined(...)
#else
#endif
always results in using either the #ifdef or the #else condition, never the #elseif. But substituting #elif causes it to work as expected based on what's defined. What convoluted purpose, if any, is served by the existence of #elseif? And if none, why doesn't the preprocessor complain?
Maybe this is why for years (decades, really), I've been using ugly #else/#endif blocks, since at least they're reliable!

#elseif is not defined. The preprocessor doesn't complain because your #ifdef is false, and the directives within that #ifdef block are not parsed. To illustrate it, this code is valid:
#if 0
#random nonsense
#else
// This must be valid
#endif

I just uncovered in IAR Embedded Workbench for MSP430, v7.11.1, which reports icc430 --version as "IAR C/C++ Compiler V7.11.1.983/W32 for MSP430",
that #elseif compiles without error, but does NOT evaluate the same as #elif.

Related

Use emscripten from Clang compiled executable

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.

Clang compiles code in GCC define block [duplicate]

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)

Printing the c++ compiler name

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

Preprocessor directives and #error

I want to show error when someone try to compile my code under other system than WIN32 and LINUX. But this code:
#ifdef WIN32
// Some code here for windows
#elif LINUX
// Some code for linux
#else
#error OS unsupported!
#endif
But this gives me an error:
#error OS unsupported
and compiler doesn't say anything else, just error.
What is wrong?
Two issues here:
your #elif does not test for the mere existence of the symbol, but for its truth (ie. defined and non-zero). You should use #elif defined(...) and, to be consistent, #if defined(...) at the start.
the symbols you are matching for are wrong. You should use, respectively, _WIN32 and __linux__. See this reference for more platforms.
LINUX is not a standard predefined macro. You probably want to check for __linux not LINUX
I know some code checks for _WIN32 but I don't know what's correct on Windows.

cross platform macro for silencing unused variables warning

In porting a large piece of C++ code from Visual Studio (2008) to Xcode (4.4+), I encounter lines such as:
UNUSED_ALWAYS(someVar);
the UNUSED_ALWAYS(x) (through UNUSED(x)) macro expands to x which seems to silence Visual C++ just fine. It's not enough for Clang however.
With Clang, I usually use the #pragma unused x directive.
The UNUSED_ALWAYS and UNUSED macros are defined in an artificial windows.h header which I control that contains a number of utilities to help Xcode compile Windows stuff.
Is there a way to define UNUSED(x) to expand to #pragma unused x? I tried this, which Clang fails to accept:
#define UNUSED(x) #pragma unused(x)
I also tried:
#define UNUSED(x) (void)(x)
Which seems to work. Did I miss anything?
(void)x;
is fine; has always worked for me. You can't usually expand a macro to a #pragma, although there is usually a slightly different pragma syntax that can be generated from a macro (_Pragma on gcc and clang, __pragma on VisualC++).
Still, I don't actually need the (void)x anymore in C++, since you can simply not give a name to a function parameter to indicate that you don't use it:
int Example(int, int b, int)
{
... /* only uses b */
}
works perfectly fine.
Yup - you can use this approach for GCC and Clang:
#define MON_Internal_UnusedStringify(macro_arg_string_literal) #macro_arg_string_literal
#define MONUnusedParameter(macro_arg_parameter) _Pragma(MON_Internal_UnusedStringify(unused(macro_arg_parameter)))
although mine did have the (void) approach defined for clang, it appears that Clang now supports the stringify and _Pragma approach above. _Pragma is C99.
#define and #pragma both are preprocessor directives. You cannot define one macro to expand as preprocessor directive. Following would be incorrect:
#define MY_MACRO #if _WIN32
MY_MACRO cannot expand to #if _WIN32 for the compiler.
Your best bet is to define your own macro:
#define UNUSED(_var) _var