https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93989

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Here's the reduced version of your code in comment 5:

template<typename CharT>
class bstring
{
private:

  CharT*        m_dataplus;

  union
  {
    CharT        m_local_buf[16];
    unsigned     m_allocated_capacity;
  };

public:
  explicit constexpr
  bstring(int) noexcept
      : m_dataplus(m_local_buf)
  {
    m_local_buf[0] = CharT();
  }
};

constexpr void test01()
{
  constexpr bstring<char> v1({});
}

int main()
{
  test01();
}

G++ says

s.C: In function 'constexpr void test01()':
s.C:25:32: error: 'bstring<char>{((char*)(&
v1.bstring<char>::<anonymous>.bstring<char>::<unnamed union>::m_local_buf)),
bstring<char>::<unnamed union>{char [16]{'\000'}}}' is not a constant
expression
   25 |   constexpr bstring<char> v1({});
      |                                ^
s.C:25:32: error: 'bstring<char>(0)' is not a constant expression because it
refers to an incompletely initialized variable

Clang gives a more useful error:

s.C:25:27: error: constexpr variable 'v1' must be initialized by a constant
expression
  constexpr bstring<char> v1({});
                          ^~~~~~
s.C:25:27: note: pointer to subobject of 'v1' is not a constant expression
s.C:25:27: note: address of non-static constexpr variable 'v1' may differ on
each invocation of the enclosing function; add 'static' to give it a constant
address
  constexpr bstring<char> v1({});
                          ^
  static 
1 error generated.


And EDG is better than G++ but not as good as Clang:

"s.C", line 25: error: expression must have a constant value
    constexpr bstring<char> v1({});
                               ^
"s.C", line 25: note: attempt to access run-time storage
    constexpr bstring<char> v1({});
                               ^


So I think your testcase is just invalid. You can't create a constexpr
**object** of that type as a local variable. But that's not what constexpr
std::string is meant to be for anyway. You can still use non-constexpr objects
as local variables in constexpr functions:

constexpr void test02()
{
  bstring<char> v1({});
}

So I don't think this is a bug. However, the diagnostic message could be
improved to explain why it's invalid. "incompletely initialized variable" isn't
very helpful.

Reply via email to