C++ constexpr bug在clang中,但不在gcc中?

C++ constexpr bug在clang中,但不在gcc中?,c++,clang,constexpr,c++14,C++,Clang,Constexpr,C++14,让我们举一个简单的例子: #include <iostream> namespace foo { constexpr int main(int argc, char* argv[]) { // code } } int main(int argc, char* argv[]) { return foo::main(argc, argv); } 注:非constexpr函数“operator” 不能在常量表达式中使用 std::cout

让我们举一个简单的例子:

#include <iostream>

namespace foo {
    constexpr int main(int argc, char* argv[]) {
      // code
    }
}

int main(int argc, char* argv[])
{
    return foo::main(argc, argv);
}
注:非constexpr函数“operator” 不能在常量表达式中使用

    std::cout << "Hello!";
它起作用了!那一定是叮当作响的虫子?我之所以说铿锵是因为gcc抱怨:

错误:constexpr函数“constexpr int foo::main(int, char**)“”不是返回语句


所以我的结论是clang是错误的,gcc是正确的。

您在C++1y模式下编译代码,该模式包含放宽
constepr
限制的措辞,包括所有循环语句


看看是什么引入了这些变化。

所以gcc 4.8.1没有实现宽松的constexpr约束,但是clang 3.5实现了。我的错误是clang和gcc都有可变长度的数组扩展。如果我使用std::array,两个编译器都会拒绝该代码。我仍然不明白的是,如果clang允许轻松的constexpr,那么为什么它不是一个constexpr呢

这里的叮当声是正确的。

第一个示例

int arr[foo::main(argc, argv)];
在这里,代码是:

constexpr int foo::main(int argc, char* argv[]) {
  std::cout << argv[i];
  return 0;
}
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拒绝它,也不允许Clang拒绝它

第三个示例

int arr[foo::main(argc, argv)];
此处绑定的数组不是常量表达式(因为它读取的
argc
argv
不是常量)。但是,默认情况下,Clang支持可变长度数组作为扩展。您可以指定
-pedanticerrors
将clang置于严格一致模式,在该模式下,它将拒绝此代码

GCC的诊断:

错误:constexpr函数“constexpr int foo::main(int,char**)”的主体不是返回语句


在C++11和C++1y中都不正确。在C++11中,这是不正确的,因为规则更加微妙(
constexpr
函数体可以包含
typedef
s和一些其他构造,而不仅仅是
return
-语句)。在C++1y中,该规则根本不存在。

在clang 3.4上生成“constexpr函数中不允许使用语句”。您使用的是clang的哪个版本?我使用的是clang 3.5
std=C++1y
我甚至认为clang不允许constexprgeneral@ToryWebster那么,为什么要标记这个
c++11
?你的问题的答案取决于它。允许它使用
operator@Griwes我忽略了for循环的主体,因为我认为OP特别想知道这个循环。但是,是的,这很奇怪。因为
operator建议编译时至少使用
-pedantic
来避免这种情况。
int arr[foo::main(argc, argv)];
constexpr int foo::main(int argc, char* argv[]) {
  std::cout << argv[i];
  return 0;
}
constexpr int foo::main(int argc, char* argv[]) {
  for (int i = 0; i < argc; i++)
    std::cout << argv[i];
  return 0;
}
int arr[foo::main(argc, argv)];