C: Являются ли директивы #define глобальными?

Я несколько смущен выражениями #define. В библиотеках они, похоже, являются средством коммуникации в разных файлах с большим количеством #ifdef и #ifndef s.

Сказав это, теперь у меня есть два файла file1.c и file2.c, скомпилированные вместе, с #define TEST 10 внутри file2.c. Тем не менее, когда я использую TEST внутри file2.c, компилятор выдает следующее сообщение об ошибке:

'TEST' undeclared (first use in this function)

Существуют ли директивы #define global?

Ответ 1

#define не являются глобальными, они являются просто заменой, где они используются (если они объявлены в одном компиляторе)

Они являются не глобальными, они не, они нерелевантны при связывании, они применимы только к сборник.

Ответ 2

#define d являются глобальными в том смысле, что они не соответствуют нормальным правилам области видимости C. Текстовая подстановка из макроса будет применяться (почти) везде, где имя макроса появляется после его #define. (Известны исключения, если имя макроса является частью комментария или частью строкового литерала.)

Если вы определите макрос в заголовочном файле, то любой файл, который #include этот заголовочный файл, унаследует этот макрос (независимо от того, желателен он или нет), если только файл явно не #undef его после #undef.

В вашем примере file2.c не знает о макросе TEST. Как бы он узнал, чтобы получить #define из file1.c? По волшебству? Поскольку макросы выполняют текстовую подстановку в исходном коде, их нет в созданных объектных файлах. Поэтому file2.c должен знать само это правило подстановки, и если вы хотите, чтобы оно использовалось совместно несколькими файлами, этот #define должен находиться в общем заголовочном файле, который ваши .c файлы #include.

Если вы спрашиваете конкретно о том, сколько из #ifdef которое вы видите в библиотеках, работают, многие из них, вероятно, сверяются с предопределенными именами макросов, предоставленными средой компиляции. Например, компилятор C99 определяет макрос __STDC_VERSION__ который определяет языковую версию; компилятор Microsoft определяет макрос _MSC_VER. (Часто эти предопределенные макросы начинаются с начальных подчеркиваний, поскольку эти имена зарезервированы для компилятора.)

Кроме того, большинство компиляторов позволяют определять простые макросы в качестве аргументов командной строки. Например, вы можете скомпилировать свой код с помощью gcc -DNDEBUG file1.c для компиляции file.c с NDEBUG определенным для отключения assert s.

Ответ 3

вы должны сделать файл1.h и поместить свои определения там. Затем в файле2.c

#include "file1.h"

просто как пирог:)

Ответ 4

Если кто-то прочитает это позже и добавит некоторую практическую информацию:

  • В некоторых средах, таких как atmel, vs или iar, вы можете определять глобальные директивы #define. Они в основном передают эти определенные значения в прекомпилятор в некотором формате командной строки.
  • Вы можете сделать то же самое в командных командах или make файлах и т.д.
  • Arduino всегда добавляет к всем компиляциям вариант платы (обычно расположенный на аппаратном уровне \arduino\variant). В этот момент вы можете создать новую панель, содержащую ваши глобальные директивы определения, и использовать ее таким образом. Например, вы можете определить плату mega2560 (debug) из оригинального mega2560, которая содержит некоторые директивы отладки. Вы добавите ссылку на этот вариант в "boards.txt", скопировав текст и правильно изменив его.

В конце дня вам нужно будет так или иначе предоставить эту глобальную hfile или глобальную директиву компилятору.