Здравствуйте, 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.
Встречный вопрос:
А ЗАЧЕМ?