Share via


Альтернатива использованию директивы #error для проверки того, что компилятор вообще вас видит

В ответ на мое описание того, как вы можете использовать директиву #error, чтобы проверить, что компилятор вообще вас видит, некоторые комментаторы предложили альтернативы. Я никогда не заявлял, что моя техника единственная, она есть не более чем еще одна возможность, доступная вам. Вот некоторые другие возможности.

scott предложил тупо напечатать asdasdasd в файл заголовка и проверить, получите ли вы ошибку. Обычно это работает, но это может быть проблематично, если код еще не компилируется. И конечно он не компилируется, потому что причина того, что вы делаете это исследование, в первую очередь в том, что вы не можете заставить ваш код компилироваться и вы пытаетесь понять, почему. Следовательно, не всегда ясно, была ли какая-то конкретная ошибка вызвана вашим asdasdasd или же тем фактом что, говоря прямо, ваш код не компилируется. Например, после добавления вашего asdadsads в строку 41 файла problem.h, вы получаете ошибку Error: Semicolon expected at line 412 of file unrelated.h. Было ли это вызвано вашим asdasdad? Не похоже, но все же на самом деле это так, потому что препроцессированный вывод выглядел как:

 asdasdasd
int GlobalVariable;

После вашего asdasdasd, все, что было сгенерировано, было охапкой #define, #if, #endif, и #include. Ни одна из этих директив не сгенерировала вывод, потому собственно компилятор ничего не увидел; все съел препроцессор. Наконец, в unrelated.h строке 412, файл-заголовок наконец попытался сделать что-то, а не просто определить макрос, и только там была обнаружена ошибка.

Но если вы можете отследить новую ошибку в общем потоке ошибок, тогда делайте это. (Также есть запутанные случаи, где лишняя asdasdasd не привносит новую ошибку.)

Поскольку строка #error короче, чем asdasdasd, и работает в большем количестве мест, я просто пользуюсь #error.

Еще одно предложение поступило от Miguel Duarte, который предложил сгенерировать препроцессированный файл и изучить его. Это помогает, но вывод препроцессора имеет тенденцию быть огромным, и, как я заметил в первоначальной статье, директивы #define не показываются, потому найти нужное вам место может быть трудно. Также в первоначальной статье я заметил, что, если вы используете предкомпилированные файлы-заголовки Visual Studio, содержимое препроцессированного вывода может не совпадать с тем, что видит компилятор. На самом деле, это самая распространенная найденная мною причина игнорирования строки: Вы поместили директиву #include в место, которое видит препроцессор, но не видит компилятор, потому что вы нарушили одно из правил соответствия предкомпилированных заголовков, обычно правило соответствия файлов исходного кода .

 

оригинал статьи