2

I am using QT Creator to make a C++ program on Ubuntu. The program I had written was compiling fine, until I decided to start using C++11 rather than C++98 (which is the default in QT Creator). I am using my own cmake file, rather than qmake, and so to do this, I included the following line in my CMakeLists.txt file:

set(CMAKE_CXX_FLAGS "-std=c++0x")

Now, part of my code has the following (which was not written by me):

#if (linux && (i386 || __x86_64__))
#   include "Linux-x86/OniPlatformLinux-x86.h"
#elif (linux && __arm__)
#   include "Linux-Arm/OniPlatformLinux-Arm.h"
#else
#   error Unsupported Platform!
#endif

After transferring to C++11, I get an error at the line error Unsupported Platform!. This is because, from what I can see, the variable linux is not defined anywhere, although the variable __x86_64__ is defined.

Therefore, I have two questions:

1) Why is the variable linux not defined, even though I am using Linux?

2) How can I tell C++11 to ignore this error?

Thanks.

Karnivaurus
  • 22,823
  • 57
  • 147
  • 247
  • 1
    Have you tried only using `linux` without adding `__arm__`? – arc_lupus Mar 13 '15 at 12:12
  • That doesn't work, because `linux` is not defined anywhere anyway. I have also tried replacing `linux` with `unix`, but that is still not defined. – Karnivaurus Mar 13 '15 at 12:14
  • is `set(CMAKE_CXX_FLAGS "-std=c++0x")` the only change you made? Most C++98 code should compile fine in C++11 unless you relied on non standard behavior. – NathanOliver Mar 13 '15 at 12:15
  • It is not the *only* change, because I have incorporated some code from elsewhere which uses some C++11 code (such as the double ampersand for rvalue reference), which is why I needed to upgrade. However, it is the only change to my `CMakeLists.txt` file. – Karnivaurus Mar 13 '15 at 12:17
  • Have you tried to revert back all changes except changing the code in the makefile, and then let it compile? – arc_lupus Mar 13 '15 at 12:19
  • Yes, if I remove the new file which uses the C++11 code, and remove the cmake line to upgrade to C++11, then it compiles fine. However, the `linux` variable is still not defined. Therefore, this still causes the error line to fire, but it just seems that C++11 is more strict than C++98 as to whether this is allowed. If I just remove the file using the C++11 code, and then add the cmake line to upgrade to C++11, then it doesn't compile, because the `linux` variable is undefined. – Karnivaurus Mar 13 '15 at 12:20
  • Then why don't you define it somewhere? – user3528438 Mar 13 '15 at 12:28
  • @user3528438: Because it should be defined by the compiler. Defining it yourself will break the portability you get from using it. – Mike Seymour Mar 13 '15 at 12:30
  • But I haven't had to define any of the other variables, such as `__x86_64__`. So, I assume that they are defined somewhere in this other code that I am using. – Karnivaurus Mar 13 '15 at 12:33
  • @Karnivaurus: Can you get CMake to print the compile command it uses? Assuming it's using GCC, you can add `-dM` to that to dump the predefined macros. That should contain `linux` if you're building for Linux, and `__x86_64__` if you're building for that, unless something weird has happened. Also, which compiler version are you using? If it's old enough that you need to specify `0x` rather than `11`, then its C++11 support might be a bit flaky. – Mike Seymour Mar 13 '15 at 12:33
  • I tried using `set(CMAKE_CXX_FLAGS "-std=c++0x -dM")`, but that did not print anything out. Is that what you meant? – Karnivaurus Mar 13 '15 at 12:42
  • And as for my compiler version: `gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)` – Karnivaurus Mar 13 '15 at 12:45
  • touch empty.cpp; g++ -dM -E -std=c++0x empty.cpp - this command should dump your defined macros. – Sergei Nikulov Mar 13 '15 at 14:55

2 Answers2

5

The identifier linux is not reserved. A conforming compiler may not predefine it as a macro. For example, this program:

int main() {
    int linux = 0;
    return linux;
}

is perfectly valid, and a conforming compiler must accept it. Predefining linux causes the declaration to be a syntax error.

Some older compilers (including the compiler you were using, with the options you were giving it) predefine certain symbols to provide information about the target platform -- including linux to indicate a Linux system. This convention goes back to early C compilers, written before there was a distinction between reserved and unreserved identifiers.

The identifier __linux__, since it starts with two underscores, is reserved for use by the implementation, so compilers are allowed to predefine it -- and compilers for Linux systems typically do predefine it as a macro expanding to 1.

Confirm that your compiler predefines __linux__, and then change your code so it tests __linux__ rather than linux. You should also find out what reserved symbol is used instead of i386 (likely __i386__).

Related: Why does the C preprocessor interpret the word "linux" as the constant "1"?

Community
  • 1
  • 1
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
0

Change your standard-selection flag to -std=gnu++0x instead of c++0x. The gnu flavors provide some non-standard extensions, apparently including predefining the macro linux. Alternatively, check for __linux__ instead.

Casey
  • 41,449
  • 7
  • 95
  • 125