This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/69261] New: Copying char arrays during constexpr evaluation does not work reliably
- From: "jens.auer at cgi dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 13 Jan 2016 16:25:04 +0000
- Subject: [Bug c++/69261] New: Copying char arrays during constexpr evaluation does not work reliably
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69261
Bug ID: 69261
Summary: Copying char arrays during constexpr evaluation does
not work reliably
Product: gcc
Version: 5.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jens.auer at cgi dot com
Target Milestone: ---
Created attachment 37331
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37331&action=edit
Preprocessed source code
I was playing around with string processing for constexpr values, and wrote the
following program to concatenate two strings at compile time:
#include <cstdint>
#include <tuple>
#include <iostream>
using std::size_t;
template<size_t N>
struct string_constexpr
{
constexpr string_constexpr() = default;
template<size_t M>
constexpr string_constexpr( char const (&d)[M] ):
data{0}
{
static_assert( M <= N, "size!" );
for(size_t i=0; i != M; i++)
{
data[i] = d[i];
}
}
char data[N];
};
template<typename T, size_t N>
T& operator<<(T& stream, string_constexpr<N> const& str)
{
return (stream << str.data);
}
template<int N>
constexpr string_constexpr<N> s( char const (&d)[N] )
{
string_constexpr<N> c{};
for(size_t i=0; i != N; i++)
{
c.data[i] = d[i];
}
return c;
}
template<size_t N, size_t M>
constexpr auto concat(string_constexpr<N> const& s1, string_constexpr<M> const&
s2)
{
string_constexpr<N+M-1> s( s1.data );
for(size_t i=0; i != M; i++)
{
s.data[N+i-1] = s2.data[i];
}
return s;
}
template<size_t N, size_t M>
constexpr auto concat(char const (&x)[N], char const (&y)[M])
{
string_constexpr<N+M-1> tmp{x};
for(size_t i=0; i != M; i++)
{
tmp.data[N+i-1] = y[i];
}
return tmp;
}
void foo()
{
auto constexpr s1 = s( "bla" );
auto constexpr s2 = s( "blub" );
string_constexpr<8> constexpr s1s2 = concat(s1,s2);
auto constexpr c = concat("bla", "blub");
std::cout << s1.data << std::endl << s2.data << std::endl << s1s2.data <<
std::endl << c << std::endl;
}
int main()
{
foo();
return 0;
}
Executables compiled with GCC and clang produce different outputs, and I think
clang is right:
$ g++ -std=c++1y static_strings.cpp
$ ./a.out
bla
blub
blablub
$ clang++ -std=c++1y static_strings.cpp
$ ./a.out
bla
blub
blablub
blablub