请使用以下代码:
#include <array>
constexpr std::array<int, 10> a{};
static_assert(std::next(std::begin(a)) == std::begin(a) + 1);使用-std=c++17,GCC完美地编译了它,但是Clang抱怨这个表达式不是一个完整的常量表达式。看起来问题是关于std::next的,但是,它应该是constexpr in C++17。
尽管如此,std::next在std库中,而不是在编译器本身中,因此发生了一些奇怪的事情。为了使事情更好,如果将-stdlib=libc++传递给Clang,则示例编译得非常完美。
怎么一回事?谁错了谁是对的?
编辑
这一问题似乎与“哥德螺栓”中的“clang”与GCC 7.2的“工具链”有关。如果将--gcc-toolchain=/opt/compiler-explorer/gcc-snapshot参数添加到命令行中,所有操作都会完美无缺。(感谢@einpoklum,他把这一问题报告给了哥德波特-我慢了一些;)
编辑
对于每一个认为旧编译器应该为实际标准工作的人来说,很抱歉,这种考虑是毫无意义的。我说的是GCC和Clang的最后两个版本。这两个版本的主干版本都可以重现这个问题。旧的编译器与这个问题无关(相反,MSVC的行为会很有趣)。
发布于 2018-04-18 09:28:23
Wandbox编译
#include <array>
int main()
{
constexpr std::array<int, 10> a{};
static_assert(std::next(std::begin(a)) == std::begin(a) + 1);
}使用clang++ 4.0.1和命令行
clang++ prog.cc -Wall -Wextra -std=c++1z我知道错误了
prog.cc:6:18: error: static_assert expression is not an integral constant expression
static_assert(std::next(std::begin(a)) == std::begin(a) + 1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:6:18: note: non-constexpr function 'next<const int *>' cannot be used in a constant expression
/opt/wandbox/clang-4.0.1/include/c++/v1/iterator:599:1: note: declared here
next(_InputIter __x,
^
1 error generated.但是用clang++ 5.0.0 (或6.0.0或7.0.0 HEAD)编译
clang++ prog.cc -Wall -Wextra -std=c++17因此,在C++17 4.0.1 (和/或clang++使用的库)中,对clang++的支持似乎很低,并在下面的版本中进行了修正。
-编辑--
对于clang++ 5.0.0和clang++ 6.0.0,这个问题得到了证实(参见einpoklum的答案)。
因此,我认为问题在于libstdc++的版本:似乎戈博尔德使用的是一个版本(我想是旧版本),其中std::next()没有被定义为constexpr,而wandbox使用的是std::next()是constexpr的版本。
发布于 2018-04-18 10:04:19
在GodBolt.org上使用Clang6.0.0和5.0.0版本时,您的代码确实可以使用编译失败。但是-在我的系统(Lubuntu17.10)上使用clang5.0.0-3,它似乎没有错误地编译。
这是奇怪的行为。因此,对于您的问题,也许不是最好的答案,但面对这种情况,我将在bugs.llvm.org上报告,看看clang/LLVM开发人员是怎么说的。
https://stackoverflow.com/questions/49895627
复制相似问题