在后来的语言标准中,一些语言特性非常有用,编译器供应商选择将它们向后移植到早期版本中,典型的例子是if constexpr
。
这个简单的程序:
template <typename T>
constexpr int get() {
if constexpr (sizeof(T) > 10) {
return 1;
} else {
return 0;
}
}
static_assert(get<int>() == 0, "!");
static_assert(get<char[100]>() == 1, "!");
从技术上讲,根据语言规则,它需要C17,在C11中,它的格式是错误的......但无论如何,gcc和clang在-std=c++11
上都能很好地编译它。每个都发出警告。
Clang会告诉您该警告是什么,以便您可以禁用它:
foo.cxx:3:8: warning: constexpr if is a C++17 extension [-Wc++17-extensions]
if constexpr (sizeof(T) > 10) {
^
1 warning generated.
使用-Wno-C++17-extensions
对clang进行编译不会产生警告。
但gcc并没有说明警告的来源:
foo.cxx: In function ‘constexpr int get()’:
foo.cxx:3:8: warning: ‘if constexpr’ only available with -std=c++17 or -std=gnu++17
if constexpr (sizeof(T) > 10) {
^~~~~~~~~
有没有办法关闭这个警告?我知道它“只在C17上可用”,但是还有are reasons还没有完全进入C17。
3条答案
按热度按时间eufgjt7s1#
正如Marc所评论的,在当前的GCC版本中,停止这些警告的唯一方法是告诉编译器您的代码位于系统头文件中。并且如果代码位于通过
-isystem
选项找到的头中,则会自动执行此操作。您还可以修饰头文件,使GCC将其视为系统头文件,而不管其所在的目录,使用:如果代码不在头文件中,就不能说它在系统头文件中。任何不是#include'd的源文件都不会被认为是系统头文件,不管它在哪个目录中,也不管你是否使用了#pragma。
exdqitrt2#
gcc 12支持抑制特定c版本警告的选项
https://docs.adacore.com/live/wave/gcc-12.x/html/gcc/gcc.html#Warning-Options
-Wno-c17-扩展(在gcc 12和clang上都能很好地工作)
mrphzbgm3#
请记住,收入的存在是有原因的:他们告诉你,虽然这个编译器可以容忍它,但另一个运行名义上相同版本的语言的编译器可能不允许。如果你关心可移植性,你应该认真考虑避免这些新特性,或者承认你实际上是用一个完全支持它们的新版本的语言编写的。
当然,我意识到我在这里和C黑客们交谈,我们集体有点臭名昭著,因为我们无视可移植性,直接在硬件上编码。