Clang中的ConstexPR错误,但不在GCC中
constexpr bug in clang but not in gcc?
让我们以这个简单的示例:
#include <iostream>
namespace foo {
constexpr int main(int argc, char* argv[]) {
// code
}
}
int main(int argc, char* argv[])
{
return foo::main(argc, argv);
}
取决于代码,clang会抱怨或否。如果代码是:
cout << "Hello!";
return 0;
clang抱怨:
错误:constexpr函数永远不会产生常数表达式 [-winvalid-constexpr]
constexpr int main(int argc, char* argv[]) {
注意:non-constexpr函数'运算符&lt;&lt;>' 不能在恒定表达式
中使用std::cout << "Hello!";
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../../包括/c /4.8/ostream:530:5:5:5:5: 注意:在这里声明
operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
足够公平,正如我们所知,ConstexPR函数不能包含任何COUT语句。但是如果我们这样做会怎样?
for (int i = 0; i < argc; i++)
std::cout << argv[i];
Clang允许它!好的,但是即使标记为constexpr,这也不可能是constexpr函数,让我们尝试在constexpr上下文中使用它。
int arr[foo::main(argc, argv)];
它有效!所以它一定是clang错误?我之所以说clang的原因是因为GCC抱怨:
错误:constexpr函数的主体'constexpr int foo :: main(int, char **)'不是返回statement
所以我的结论是clang是错误的,而海湾合作od是正确的。
clang在此处是正确的。
第一个示例
在这里,代码为:
constexpr int foo::main(int argc, char* argv[]) {
std::cout << argv[i];
return 0;
}
在C 11 中,此代码是不形式的,因为身体包含一个表达式statement ,在constexpr
函数定义中不允许使用。<<<<<<<<<<<<<<
在C 1Y 中,此代码不需要诊断,因为foo::main
的调用永远不会产生恒定的表达式(因为它总是调用operator<<(std::ostream&, const char*)
,这不是constexpr
)。
第二个示例
在这种情况下,代码为:
constexpr int foo::main(int argc, char* argv[]) {
for (int i = 0; i < argc; i++)
std::cout << argv[i];
return 0;
}
在C 11 中,此代码不形成,因为它包含for
陈述。
在C 1y 中,此代码是有效的。特别是,foo::main(0, 0)
是一个常数表达式(具有值0
)。由于 foo::main
在恒定表达式中可用,因此不允许clang拒绝它,也不拒绝。
第三个示例
int arr[foo::main(argc, argv)];
此处绑定的数组是不是常数表达式(因为它读取 argc
和 argv
,这不是恒定的)。但是,Clang默认情况下支持可变长度数组作为扩展名。您可以指定-pedantic-errors
将Clang放置在严格的组合模式中,并且在该模式下它会拒绝此代码。
GCC的诊断:
错误:constexpr函数的主体'constexpr int foo :: main(int,char **)'不是返回statement
在C 11和C 1Y中都是不正确的。在C 11中,这是不正确的,因为该规则更微妙(constexpr
功能的主体可以包含typedef
s和其他一些构造,而不仅仅是return
列表)。在C 1Y中,该规则根本不再存在。
您以C 1Y模式编译代码,其中包含措辞放松constexpr
限制,包括所有循环语句。
请查看引入这些更改的N3652。
因此,GCC 4.8.1不会实现放松的ConstexPr限制,但是Clang 3.5确实如此。我的错误是Clang和GCC都具有可变的长度阵列扩展。如果我使用std ::数组,则两个编译器都会拒绝代码。我仍然不明白的是,如果Clang允许放松的Constexpr,那么为什么不是Constexpr?
- 理解GCC中的std::pow实现
- -fvisibility-inline-hidden 与 gcc 中的 -fvisibility=hidden 有何不同
- gcc 中的多个对齐属性是否可以用于保证缓存行分隔?
- 转换为标准时,Clang和GCC中的不同结果::可选<T>
- gcc 中的模棱两可的运算符
- std::可选的默认构造函数不是 gcc 中的 constexpr?
- 为什么包含会<utility>破坏 GCC 中的结构化绑定?
- 如何将GCC中的静态库与其他动态库链接
- GCC 中的库连接
- Docker GCC中的C 11:5图像
- GCC中的模板实例与视觉C 不同
- GCC 中的编译器错误,但在将 decltype 与具有尾随返回类型语法的模板化成员函数一起使用时没有 clang
- gcc中的可变延长阵列
- 将函数返回值传递给引用参数会导致 GCC 中的编译错误
- gcc 中的模板显式实例化(定义和声明)
- 如何使用某些参数展开某个循环,例如 GCC 中的最大展开时间
- clang和gcc中的这个警告似乎不正确
- 如何在不将库源代码添加到我的项目中的情况下将库链接到 CodeBlocks 和 GCC 中的项目
- GCC中的CRTP与失机会标志
- __has_trivial_copy在clang和gcc中的行为不同.谁'是吗