2016-04-27 2 views
2

Я хочу знать, является ли соответствующий компилятор C++ требуется поддерживать следующий код:рекурсивный спуск парсер, инициализация переменной с самим собой, дилемма

int a(a);  // no other a is visible, we mean initialization of a with itself 

Visual Studio 2013 не поддерживает его (необъявленный идентификатор), однако некоторые компиляторы компилируют его.

И вот наша дилемма: для возможной проверки выражения нам необходимо распорядиться информацией о a (включая его тип), поскольку она может быть частью выражения, однако есть и другая возможность, что она является функцией, в этом случае мы только выражение типа построения (и символ a, вероятно, еще не находится в таблице символов).

Я думаю, что рекурсивный парсер спуска, скорее всего, столкнется с этой дилеммой, поскольку он является очень структурным по своей природе, и поддержка этого конкретного случая будет похожа на специальный «костыль» (выражение типа строится, когда мы сталкиваемся с a внутри (), и мы находимся на определенном уровне рекурсии). Поэтому я предполагаю, что визуальная студия использует рекурсивную стратегию спуска.

Итак, имея в виду, стоит ли прилагать усилия автора-писателя и оправдан ли поддерживать такой код (особенно при использовании рекурсивного спуска)?

+1

У вас есть UB для инициализации 'a' с еще не инициализированным' a'. – Jarod42

+2

, но вы можете иметь 'void * p (&p); // Имеет свой собственный адрес'. – Jarod42

+0

Пример' int x = x; 'в 3.3.2, кажется, указывает, что это законно, и соответствующий компилятор должен его принять. Http : //www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf – Henrik

ответ

1

[basic.scope.pdecl]

точка декларации для имени сразу после его полного описателя (пункт 8) и до его инициализатора (если таковые имеются), за исключением случаев, , указанный ниже. [Пример:

unsigned char x = 12; 
{ unsigned char x = x; } 

Здесь вторые й инициализируются со своим собственным (неопределенным) значением. -end пример]

В int a(a);, описатель заканчивается на открытии фигурной скобкой инициализаторе, да так, составители должны позволить этому (GCC услужливо дает -Wuninitialized предупреждение, если это автоматическая переменная).

+0

Исправить, с рекурсивным анализом спуска, встречая первый '(' будет соответствовать объявлению «целочисленной переменной», и поэтому к настоящему времени «а» знакомо компилятору.Но будет больше производств, которые прячут компилятор для генерации кода инициализации для этой переменной при виде '('. К настоящему времени, поскольку «a» знаком, поэтому нет проблемы с его использованием в качестве значения внутри «()», хотя он будет содержать мусор значение – sameerkn

+0

Что об этом:. 'структуры а { INT v; а() { v = 12349; соиЬ << "а()" << епсИ; } а (интермедиат с) { противов = c; cout << "abc (int)" << endl; } }; 'abc a (av)' Что все будет напечатано? – sameerkn

+1

@sameerkn: UB, вы вызываете 'abc (int) 'с неинициализированным' int', который вы читаете. – Jarod42

Смежные вопросы