Повторное использование макроса C в нескольких файлах

У меня есть несколько часто используемых макросов, которые необходимы почти в каждом C-файле, который я пишу. В настоящее время я копирую их в каждый файл, в котором они мне нужны. Вероятно, это плохая идея, потому что в конечном итоге мне нужно будет изменить один из них, и тогда я получу несогласованно определенные макросы между файлами.

Есть ли способ создать заголовочный файл для макросов? Я попытался создать заголовок со всеми моими макросами и включить его, но все равно получаю предупреждения компилятора.

ОБНОВЛЕНИЕ. Конкретные предупреждения, которые я получаю, являются неявными объявлениями функций, таких как V4 из второго примера.

Пример:

файл1.с:

#define COMMON_NUMBER 1

файл2.с:

#define COMMON_NUMBER 1

//...

файлN.c:

#define COMMON_NUMBER 1

//Oh wait, it should have been 2 all along..... *facepalm*

Лучший пример:

файл1.с:

#include "usefulmacros.h"

char* prog;
int optv;

int main(){
  prog = strdup(argv[0]);    
  optv = 4;           // This would be parsed from # of "-v" in argv[]
  return 0;
}

void functionA(){
  int dumberror = 1;
  V4("This is a fairly verbose error: %d",dumberror);
}

файл2.с:

#include "usefulmacros.h"
extern char* prog;
extern int   optv;

void functionB(){
  int differror = 2;
  V4("This is a different error: %d",differror);
}

полезные макросы.h:

#ifndef USEFULMACROS
#define V4(str, ...) if(optv >= 4){printf("%s: "str,prog,__VA_ARGS__);}
#endif

person Huckle    schedule 05.03.2012    source источник
comment
О каких предупреждениях вы говорите здесь? Догадаемся?   -  person Jeff Mercado    schedule 06.03.2012
comment
Если вы еще не слышали, очень мало задач, для которых макросы являются лучшим инструментом, и они могут вызвать много проблем. Например, эта COMMON_NUMBER может быть глобальной переменной const (или лучше).   -  person Beta    schedule 06.03.2012
comment
@JeffMercado: я обновил свой вопрос лучшим примером, который иллюстрирует то, что происходит в более конкретном смысле.   -  person Huckle    schedule 06.03.2012
comment
@Huckle Пожалуйста, посмотрите правку моего ответа - я думаю, вам не хватает важного #define в вашем usefulmacros.h.   -  person Sergey Kalinichenko    schedule 06.03.2012
comment
@Beta Нет, если он должен использоваться в условных выражениях препроцессора или целочисленных константных выражениях (метки регистра, размеры массивов, размеры битовых полей, статические значения утверждений и т. д.). C++ допускает выражения, основанные на константных объектах из последней группы, а стандартный C — нет.   -  person PSkocik    schedule 06.02.2020


Ответы (4)


#ifndef COMMON_INCLUDE_FILE
#define COMMON_INCLUDE_FILE

#define COMMON_NUMBER 1
#define OTHER_COMMON 2

#endif

В C, где макросы немного более распространены, чем в C++, где вы хотели бы сделать это со статическим глобальным, описанный выше механизм довольно распространен. Вы помещаете охранники включения вокруг тела файла и определяете там свои общие ресурсы. По сути, это то, чем config.h заканчивается с autoconf. Так что никто не может сказать, что это не стандартный механизм для кода C.

Просто включите common.h в любые файлы, которые в нем нуждаются, готово.

person synthesizerpatel    schedule 05.03.2012
comment
Я знаю о структуре #idndef/#define/#endif, я добавил больше деталей в свой вопрос. - person Huckle; 06.03.2012
comment
Это все тот же ответ, что и я, обратите внимание, что в вашем вопросе все еще отсутствует важный '#ifndef COMMON_INCLUDE_FILE\n #define COMMON_INCLUDE_FILE\n ‹Actual_common_things›\n #endif\n'.. В частности, это защита заголовка, которая предотвращает предварительную обработку вашего включения несколько раз (и является причиной ваших ошибок определения дубликатов. При последующем включении, если COMMON_INCLUDE_FILE определен, он не будет повторно предварительно обрабатывать Это. - person synthesizerpatel; 06.03.2012

Вы определенно должны поместить свои общие макросы в один заголовок для всего вашего проекта: дублирование кода — опасная вещь, которая увеличивает ваши затраты на обслуживание.

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

ИЗМЕНИТЬ (в ответ на обновление вопроса)

В вашей реализации include guards отсутствует #define USEFULMACROS. Это должно быть следующим образом:

//usefulmacros.h
#ifndef USEFULMACROS
#define USEFULMACROS
#define V4(str, ...) if(optv >= 4){printf("%s: "str,prog,__VA_ARGS__);}
#endif
person Sergey Kalinichenko    schedule 05.03.2012
comment
Хороший и точный ответ, +1. Но есть одна вещь, на которую стоит намекнуть: Предупреждения, которые вы видите, могут быть связаны с включением одного и того же заголовка несколько раз. — Проблема не в точном включении одного и того же файла заголовка несколько раз; это связано с тем, что определение макроса USEFULMACROS отсутствует, и, следовательно, соответствующие вложенные макросы несуществующего USEFULMACROS пытаются переопределить при любом последующем включении файла заголовка usefulmacros.h. - person RobertS supports Monica Cellio; 06.02.2020

То, что вы описываете, - это способ сделать это. Какое предупреждение? Если это множественное определение, вы просто хотите защитить файл, как описано в ответе на этот вопрос: add-multiple-times">При использовании #ifndef файл .h добавляется несколько раз

person Joe    schedule 05.03.2012

Вы проверяете определение макроса USEFULMACROS с помощью #ifndef, но нигде его не определяли.

Вы должны добавить строку

#define USEFULMACROS

после

#ifndef USEFULMACROS
person dAm2K    schedule 06.03.2012