Подтвердить что ты не робот

Смешивание объявлений constexpr и определений констант

Я столкнулся со следующей ситуацией:

struct Foo
{
    static constexpr char s[] = "Hello world";
};

const char Foo::s[];

Этот фрагмент кода компилируется с помощью Clang 3.7 (с -std=c++11 и -std=c++14), но GCC (4.8, 6.0, те же настройки языка) дает ошибку, которую я ожидал бы:

GCC 4.8:

in.cpp:6:19: error: redeclaration ‘Foo::s’ differs in ‘constexpr’
 const char Foo::s[];
                   ^
in.cpp:3:27: error: from previous declaration ‘Foo::s’
     static constexpr char s[] = "Hello world";
                           ^
in.cpp:6:19: error: declaration of ‘constexpr const char Foo::s [12]’ outside of class is not definition [-fpermissive]
 const char Foo::s[];

GCC 6.0:

‘constexpr’ needed for in-class initialization of static data member ‘const char Foo::s [12]’ of non-integral type [-fpermissive]

Я нашел этот старый вопрос, который, по-видимому, обсуждает смешение constexpr и const, но он фокусируется на том, являются ли инициализаторы постоянными выражениями, а не являются ли определения и декларация может отличаться в отношении константы.

Можно ли предоставить определение для статического элемента данных constexpr T как const T?

4b9b3361

Ответ 1

Ваш код хорошо сформирован. constexpr -спецификатор не является частью этого типа, но добавляет const ([dcl.constexpr]/9), который присутствует во втором объявлении. Хотя разные объявления одной функции (или шаблона функции) должны согласовываться в constexpr -ness в соответствии с [dcl.constexpr]/1, такое правило не существует для объявлений переменных.

Смотрите ошибку # 58541, которая в основном использует ваш пример.