Upgrading from C++98 to C++11 causes error
我正在使用QT Creator在Ubuntu上制作C ++程序。 我编写的程序编译得很好,直到我决定开始使用C ++ 11而不是C ++ 98(这是QT Creator中的默认设置)。 我使用自己的cmake文件,而不是qmake,所以要做到这一点,我在CMakeLists.txt file中包含以下行:
1
| set(CMAKE_CXX_FLAGS"-std=c++0x") |
现在,我的部分代码有以下内容(不是我编写的):
1 2 3 4 5 6 7
| #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 |
转移到C ++ 11后,我在error Unsupported Platform!行遇到错误。 这是因为,从我所看到的,变量linux没有在任何地方定义,尽管定义了变量__x86_64__。
因此,我有两个问题:
1)为什么变量linux没有定义,即使我使用的是Linux?
2)如何告诉C ++ 11忽略此错误?
谢谢。
-
您是否尝试过仅使用linux而不添加__arm__?
-
这不起作用,因为linux无论如何都没有在任何地方定义。我也尝试用unix替换linux,但仍未定义。
-
是set(CMAKE_CXX_FLAGS"-std=c++0x")你做出的唯一改变?除非你依赖非标准行为,否则大多数C ++ 98代码应该在C ++ 11中编译得很好。
-
这不是唯一的变化,因为我已经在其他地方使用了一些使用一些C ++ 11代码的代码(例如用于右值参考的双&符号),这就是我需要升级的原因。但是,它是我的CMakeLists.txt文件的唯一更改。
-
您是否尝试恢复所有更改,除了更改makefile中的代码,然后让它编译?
-
是的,如果我删除使用C ++ 11代码的新文件,并删除cmake行以升级到C ++ 11,那么它编译得很好。但是,linux变量仍未定义。因此,这仍然会导致错误行触发,但似乎C ++ 11比C ++ 98更严格,因为这是否允许。如果我只是使用C ++ 11代码删除文件,然后添加cmake行以升级到C ++ 11,那么它不会编译,因为linux变量未定义。
-
那你为什么不在某处定义呢?
-
@ user3528438:因为它应该由编译器定义。自己定义会破坏使用它的可移植性。
-
但我不必定义任何其他变量,例如__x86_64__。所以,我认为它们是在我正在使用的其他代码中的某个地方定义的。
-
@Karnivaurus:你能让CMake打印它使用的编译命令吗?假设它正在使用GCC,您可以将-dM添加到其中以转储预定义的宏。如果你正在为Linux构建,那应该包含linux,如果你正在构建,那么应该包含__x86_64__,除非发生了奇怪的事情。另外,您使用的是哪个编译器版本?如果它足够大,你需要指定0x而不是11,那么它的C ++ 11支持可能有点不稳定。
-
我尝试使用set(CMAKE_CXX_FLAGS"-std=c++0x -dM"),但没有打印任何东西。这是你的意思吗?
-
至于我的编译器版本:gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
-
触摸empty.cpp; g ++ -dM -E -std = c ++ 0x empty.cpp - 此命令应转储已定义的宏。
标识符linux未保留。符合标准的编译器可能不会将其预定义为宏。例如,这个程序:
1 2 3 4
| int main() {
int linux = 0;
return linux;
} |
完全有效,符合标准的编译器必须接受它。预定义linux会导致声明为语法错误。
一些较旧的编译器(包括您使用的编译器,以及您提供的选项)预定义某些符号以提供有关目标平台的信息 - 包括linux以指示Linux系统。这个约定可以追溯到早期的C编译器,在保留和未保留标识符之间有区别之前编写。
标识符__linux__,因为它以两个下划线开头,保留供实现使用,因此允许编译器预定义它 - 而Linux系统的编译器通常会将其预定义为扩展为1的宏。
确认您的编译器预定义__linux__,然后更改代码,使其测试__linux__而不是linux。您还应该找出使用的保留符号而不是i386(可能是__i386__)。
相关:为什么C预处理器将单词"linux"解释为常量"1"?
将标准选择标志更改为-std=gnu++0x而不是c++0x。 gnu风格提供了一些非标准扩展,显然包括预定义宏linux。或者,检查__linux__。