Этот ответ на другой вопрос актуален.
Когда вы делаете странные уловки препроцессора (которые являются законными), полезно попросить компилятор сгенерировать предварительно обработанную форму (например, с помощью gcc -C -E
при использовании GCC ) и посмотреть на эту предварительно обработанную форму.
На практике для исходного файла foo.c
имеет смысл (иногда) получить предварительно обработанную форму foo.i
с gcc -C -E foo.c > foo.i
и посмотреть на нее foo.i
.
Иногда даже имеет смысл получить это foo.i
без информации о строке. Хитрость здесь (удаление информации о строках, содержащейся в строках, начинающихся с #
) заключается в следующем:
gcc -C -E foo.c | grep -v '^#' > foo.i
Тогда вы можете indent foo.i
и скомпилировать его, например. с gcc -Wall -c foo.i
; вы обнаружите места ошибок в предварительно обработанном файле, и вы сможете понять, как вы это получили, и вернуться к своим макросам препроцессора (или их вызовам).
Помните, что препроцессор C в основном представляет собой текстовое преобразование, работающее на уровне файлов. Невозможно макроразвернуть несколько строк в изоляции (поскольку предыдущие строки могли воспроизводиться с #if
в сочетании с #define
- возможно, в предыдущих #include
-d файлах - или опции препроцессора , такие как -DNDEBUG
, переданные в gcc
или g++
). В Linux см. Также feature_test_macros (7)
Известный пример расширения, которое работает по-разному при компиляции с -DNDEBUG
или без него, переданного компилятору: assert
. Значение assert(i++ > 0)
(что очень неправильно для кода) зависит от него и показывает, что макроразложение не может быть выполнено локально (и вы можете представить себе какой-то предыдущий заголовок, имеющий #define NDEBUG 1
, даже если, конечно, это плохой вкус).
Другим примером (на самом деле очень распространенным), где расширение макроса зависит от контекста, является любой макрос, использующий __LINE__
или __COUNTER__
...
NB. Вам не нужен Eclipse для всего этого, достаточно хороший редактор исходного кода (я предпочитаю emacs , но это дело вкуса): для задачи предварительной обработки вы можете использовать ваш компилятор.