Альтернатива использованию директивы #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
в место, которое видит препроцессор, но не видит компилятор, потому что вы нарушили одно из правил соответствия предкомпилированных заголовков, обычно правило соответствия файлов исходного кода .