Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clang, std::next, libstdc++ and constexpr-ness

Take the following code:

#include <array>

constexpr std::array<int, 10> a{};
static_assert(std::next(std::begin(a)) == std::begin(a) + 1);

With -std=c++17 GCC compiles it flawlessly, but Clang complains that the expression is not an integral constant expression. It looks like that the problem is about the std::next which, however, should be constexpr in C++17.

Nevertheless, std::next is in the std library, not in the compiler itself, therefore there is something weird going on. And just to make things even better, the example compiles perfectly if you pass -stdlib=libc++ to Clang.

What is going on? Who is wrong and who is right?

EDIT

The issue seems to be related to clang being toolchain-ed against GCC 7.2 inside godbolt. If you add the --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot parameter to the command line, everything works flawlessly. (Thanks to @einpoklum who reported the issue to godbolt -- I have been slower ;) )

EDIT

For everyone who consider that an old compiler should work for actual standard, sorry to say that the consideration is meaningless. I am talking about the last versions of both GCC and Clang. And the problem is reproducible with the trunk version of both. Older compilers are not relevant for this question (MSVC behaviour would be interesting, instead).

like image 864
dodomorandi Avatar asked Apr 18 '18 09:04

dodomorandi


1 Answers

Compiling in Wandbox

#include <array>

int main()
 {
   constexpr std::array<int, 10> a{};
   static_assert(std::next(std::begin(a)) == std::begin(a) + 1);
 }

with clang++ 4.0.1 and command line

clang++ prog.cc -Wall -Wextra -std=c++1z

I get the error

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.

But compiling with clang++ 5.0.0 (or 6.0.0 or 7.0.0 HEAD) with

clang++ prog.cc -Wall -Wextra -std=c++17

So it seems a low support for C++17 in clang++ 4.0.1 (and/or libraries used by clang++), corrected in the following versions.

-- EDIT --

The problem is confirmed (see einpoklum's answer) for clang++ 5.0.0 and clang++ 6.0.0 in gobold.

So I suppose the problem is the version of libstdc++: seems that gobold is using a version (a older one, I suppose) where std::next() isn't defined as constexpr where wandbox is using a version where std::next() is constexpr.

like image 54
max66 Avatar answered Sep 24 '22 07:09

max66