Re: Дурацкий вопрос
От: Кодт Россия  
Дата: 26.11.24 00:13
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Почему 2 и 3 строчки не константы ?

_>
_>const int c1=(char*)1-(char*)0;
_>enum { c2=(char*)1-(char*)0 };
_>constexpr int c3=(char*)1-(char*)0;
_>


Потому что это всё — не константы времени компиляции?

Адресная арифметика определена только в пределах одного массива.
За его пределами — поведение как минимум, не специфицировано. (А точнее, это UB, на которое все закрывают глаза).

Даже вот так — нельзя
char x;
char y;

constexpr int d = &y - &x;

потому что разность адресов независимых объектов выяснится только на стадии линковки.

А вот так — можно
char x[] = "12345";

constexpr int d = &x[3] - &x[1];

потому что где бы ни был размещён массив, но смещения элементов друг относительно друга там известны сразу.

А вот так — gcc считает, что можно, а clang — что нельзя
struct foo {
  char x;
  int y;
  char z;
};

foo f;

constexpr int d = &f.z - &f.x;

И я, пожалуй, соглашусь с clang: потому что в общем случае можно нахимичить с выравниванием, и для типов, чей sizeof не равен 1, адресная арифметика окажется дробной.

Надо покурить стандарт, где должно быть сказано, что при наличии таких хаков (а тем более, реинтерпретов (char*)1) программа становится ill-formed, no diagnostic required.

Встречный вопрос:
А ЗАЧЕМ?
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.