Почему оно работает? Слышал об предварительном объявлении, но это явно другой случай. Или в чистом виде UB?
#include <iostream>
using namespace std;
const int x = 5;
int main(){
int x[x];
cout << "OK!" << endl;
return 0;
}
Почему оно работает? Слышал об предварительном объявлении, но это явно другой случай. Или в чистом виде UB?
#include <iostream>
using namespace std;
const int x = 5;
int main(){
int x[x];
cout << "OK!" << endl;
return 0;
}
Нет, это не UB. Согласно стандарту, раздел 6.3.2, клауза 2 упоминает в точности ваш пример:
const int i = 2;
{ int i[i]; }
В нём определяется массив из двух целых чисел внутри блока.
Полная цитата из стандарта (перевод мой):
Точка декларации имени находится непосредственно за её полным декларатором (...) и перед инициализатором (если он есть), за исключением замечаний ниже. [ Пример:
unsigned char x = 12;
{ unsigned char x = x; }
Здесь второй x инициализируется своим собственным (неопределённым) значением. — конец примера ]
[ Замечание: Имя из внешней области действует вплоть до точки декларации имени, которое его перекрывает. [ Пример:
const int i = 2;
{ int i[i]; }
определяет внутриблоковый массив из двух целых. — конец примера ] — конец замечания ]
x)
– avp
Nov 12 '17 at 22:05
void* p = { (void*)p, NULL }. Без этого сослаться на себя было бы сложно.
– VladD
Nov 12 '17 at 22:27
p тут инициализируется нулем. На самом деле ссылка на себя больше всего мешает в макросах, поскольку передаваемое имя неизвестно.
– avp
Nov 12 '17 at 23:12
void* p[] = { (void*)p, NULL }. Массив указателей.
– VladD
Nov 12 '17 at 23:18
[x]является частью объявления типа переменной, гдеxпока еще не обозначает локальную переменную, но как только объявление заканчиваетсяxуже будет обозначать именно локальную переменнуюint x[x]{x}; // ошибка– user7860670 Nov 12 '17 at 21:07