Какой хороший способ проверить, что идентификаторы не обрезаются и не смешиваются? - PullRequest
4 голосов
/ 13 сентября 2011

Сегодня в классе C ++ мы обсудили максимально возможную длину идентификаторов и то, как компилятор в конечном итоге прекратит обрабатывать переменные как разные после определенной длины.(Кажется, мой профессор подразумевал, что действительно длинные идентификаторы усекаются.) Я опубликовал еще один вопрос ранее, надеясь увидеть, определено ли где-нибудь ограничение .Мой вопрос здесь немного другой.Предположим, я хотел проверить практическое или принудительное ограничение на длину имени идентификатора.Как бы я поступил так?Вот что я думаю сделать, но как-то это кажется слишком простым.

  • Шаг 1: Создайте как минимум две переменные с действительно длинными именами и напечатайте их вприставка.Если имена идентификаторов действительно так безграничны, я не собираюсь тратить время на их ввод.Мой код должен сделать это для меня.
  • Шаг 2: Попытка выполнить некоторые операции с переменными, например сравнить их или любую арифметику.Если компилятор прекратит дифференцирование, то теоретически определенная арифметика будет нарушена, например, x/(reallyLongA-reallyLongB), поскольку reallyLongA и reallyLongB будут такими длинными, что компилятор будет рассматривать их как одно и то же.В этот момент операция деления станет делением на ноль, что должно привести к сбою и ужасному сгоранию.

Правильно ли я подхожу к этому?У меня закончится память до того, как я "сломаю" компилятор или "время выполнения"?

Ответы [ 3 ]

5 голосов
/ 13 сентября 2011

Я не думаю, что вам даже нужно генерировать какие-либо операции с переменными.

Следующий код сгенерирует ошибку переопределения во время компиляции;

int name;
int name;

Я ожидаювы получите ту же ошибку с

int namewithlastsignificantcharacterhere_abc;
int namewithlastsignificantcharacterhere_123;

Я бы использовал макрос язык сценариев для генерации более длинных имен, пока вы не получите одно, которое сломалось.Вот один строковый Ruby

C:> ruby ​​-e "(1..2048) .each {| i | put \" int # {'variable' * i} # {i}; \ "}"> var.txt

Когда я #include var.txt в файле ac и компилирую с VS2008, я получаю ошибку

"1>c: \ code \ quiz \ var.txt (512): фатальная ошибка C1064: ограничение компилятора: переполнение токена внутренним буфером "

и 512 * 8 символов - это 4096, на которые ссылается JRL.

4 голосов
/ 13 сентября 2011

Ваш профессор не прав.§ 2.11 / 1 стандарта C ++ гласит: « Все символы значимы».Конечно, компиляторы могут наложить ограничение на допустимую длину, как отмечено в вашем другом вопросе.Это не значит, что они могут игнорировать символов после этого.

Он, вероятно, путает C и C ++.Два языка имеют похожие, но не идентичные правила.Исторически, у C было ограничение в шесть значащих символов.

Что касается вашего теста, существует гораздо более простой способ проверить вашу гипотезу.Обратите внимание, что

int a;
int a;

недопустимо, поскольку вы определяете один и тот же идентификатор дважды.Теперь , если ReallyLongNameA и ReallyLongNameB будут отличаться только незначительными символами, тогда

int ReallyLongNameA;
int ReallyLongNameB;

также будет ошибкой во время компиляции, поскольку оба будут объявлять одну и ту же переменную,Вам не нужно запускать код.Вы можете просто сгенерировать test.cpp с этими двумя строками и попытаться скомпилировать его.Итак, напишите небольшую тестовую программу, которая создает все более длинные имена идентификаторов, запишите их в test.cpp и вызовите system("path/to/compiler -compileroptions test.cpp");, чтобы посмотреть, скомпилируется ли она.

4 голосов
/ 13 сентября 2011

Для Windows C ++ :

Значимы только первые 2048 символов идентификаторов Microsoft C ++.Имена для пользовательских типов «декорированы» компилятором для сохранения информации о типе.Результирующее имя, включая информацию о типе, не может быть длиннее 2048 символов.

Таким образом, вы можете сделать довольно простой тест с использованием компилятора MS, по крайней мере.

Редактировать: Не проводилось подробное тестирование, но по крайней мере на моем Visual Studio Pro 2008 компилируется переменная с именем aaaa ... (общая длина 4095 символов), и после этого (> = 4096 вы получаете Fatal Error C1064: compiler limit : token overflowed internal buffer).

...