2

I have some problems with aggregate initialization of a union containing std::string evaluated in constant expression. This example program demonstrates it:

constexpr bool f() {
    union U{
        std::string s;
        constexpr ~U(){ s.~basic_string(); }
    } u{};
    return true;
}

static_assert( f() );

I assume that u{} shall set std::string s; as active union member and default initialize it. And indeed it work in MSVC and in Clang with libc++. But in Clang with libstdc++ or in GCC it produces the error:

error: non-constant condition for static assertion
   in 'constexpr' expansion of 'f()'
   in 'constexpr' expansion of '(& u)->f()::U::~U()'
   in 'constexpr' expansion of '((f()::U*)this)->f()::U::s.std::__cxx11::basic_string<char>::~basic_string()'
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.h:803:19:   in 'constexpr' expansion of '((std::__cxx11::basic_string<char>*)this)->std::__cxx11::basic_string<char>::_M_dispose()'
error: accessing 'std::__cxx11::basic_string<char>::<unnamed union>::_M_allocated_capacity' member instead of initialized 'std::__cxx11::basic_string<char>::<unnamed union>::_M_local_buf' member in constant expression

Online demo: https://gcc.godbolt.org/z/bbf4Yo3v9

The error in GCC can be eliminated by adding default initializer to

std::string s{};

by Clang still prints the error:

: error: static assertion expression is not an integral constant expression
include/c++/12.2.0/bits/basic_string.h:356:10: note: assignment to member '_M_local_buf' of union with no active member is not allowed in a constant expression
            __c = _CharT();
                ^
include/c++/12.2.0/bits/basic_string.h:519:2: note: in call to '&u.s->_M_use_local_data()'
        _M_use_local_data();
        ^
note: in call to 'basic_string()'
        std::string s{};
                     ^

Online demo: https://gcc.godbolt.org/z/q84vcMTef

Is it just an issue with libstdc++ or the program is ill formed?

Fedor
  • 17,146
  • 13
  • 40
  • 131
  • 1
    Fwiw: `u{{}};` works in gcc (but not in clang when using `libstdc++`). Perhaps the language-lawyer tag would be appropriate on this one? – Ted Lyngmo Jun 06 '23 at 19:33
  • 1
    Clang's issue with libstdc++ is a duplicate of https://stackoverflow.com/questions/73684176/clang-constexpr-compile-error-in-lambda-gcc-and-msvc-ok-clang-bug, which has been fixed for GCC 13.1 / 12.3 libstdc++ releases, but your compiler explorer link is using GCC 12.2's libstdc++. Choosing Clang trunk it compiles fine. GCC's issue seems to be a compiler bug to me. – user17732522 Jun 06 '23 at 20:50
  • 2
    I guess the GCC bug is the same one as in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103924. – user17732522 Jun 06 '23 at 21:00

0 Answers0