Мы знаем, что операции которые вызывают поведение undefined, не являются основными константными выражениями (раздел 5.19 параграфа 2 из черновик стандарта С++)
В тестах я выполнял как clang
, так и gcc
поведение undefined в constexpr как ошибку, но они несовместимы в случае сдвига вправо влево. Например, во всех этих случаях, которые рассматриваются как поведение undefined в соответствии с разделом 5.8
Операторы сдвига с 1 по 3:
constexpr int x1 = 1 << 33 ; //Assuming 32-bit int
constexpr int x2 = 1 << -1 ;
constexpr int x3 = -1 << 1 ;
constexpr int x4 = 1 >> 33 ; //Assuming 32-bit int
constexpr int x5 = 1 >> -1 ;
clang
приведет к ошибке (увидеть его в прямом эфире):
error: constexpr variable 'x1' must be initialized by a constant expression
constexpr int x1 = 1 << 33 ; //Assuming 32-bit int
^ ~~~~~~~
note: shift count 33 >= width of type 'int' (32 bits)
constexpr int x1 = 1 << 33 ; //Assuming 32-bit int
....
while gcc
выдаст предупреждение, но все равно будет считать, что каждая переменная является постоянным выражением (видеть ее в прямом эфире):
warning: left shift count >= width of type [enabled by default]
constexpr int x1 = 1 << 33 ; //Assuming 32-bit int
^
warning: left shift count is negative [enabled by default]
constexpr int x2 = 1 << -1 ;
...
Это выглядит как ошибка gcc
, но я знаю, что компилятор может сделать более сильные гарантии для поведения, который, по словам стандарта, undefined, и он выглядит как gcc дает более сильные гарантии для смены. Это может оказаться ошибкой, но это заставляет меня задаться вопросом, разрешил ли компилятор тот же доступ в контексте constexpr
, или компилятор должен строго придерживаться того, что говорит стандарт, - это поведение undefined здесь?
Обновить
Как упоминает Алан, действительно верно, что диагностика плохо сформированной программы может быть либо ошибкой, либо предупреждением, но в этом случае gcc
, похоже, не считает программу плохо сформированной. В отличие от других экземпляров, например, в случае overflow, gcc
не жалуется на недопустимый constexpr, но предупреждает о смене. Таким образом, казалось бы, либо это ошибка, либо gcc
не рассматривает эти случаи как undefined и, следовательно, мой вопрос.