This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/69261] New: Copying char arrays during constexpr evaluation does not work reliably


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]