Область действия и условные #define в C - PullRequest
0 голосов
/ 28 сентября 2018

Я хочу использовать локальный файл .h для определения тех же имен, которые используются в моей библиотеке.Моя библиотека имеет определение значения по умолчанию для этих имен, но я бы хотел изменить это значение по умолчанию, используя локальный файл .h.Тем не менее, у меня есть нежелательное поведение.Как я могу решить это?

test.c

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#include "conf.h"
#include "mylib.h"

int main ()
{
  printf("Value in main: %d\n", NAMEDEFINITION);
  fn();

  return 0;
}

conf.h

#define NAMEDEFINITION 42 

mylib.h

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#ifndef NAMEDEFINITION
  #define NAMEDEFINITION 84 
#endif

void fn(); 

mylib.c

#include "mylib.h"

void fn()
{
  printf("Value in fn: %d\n", NAMEDEFINITION);
  return;
}

Моя строка компиляции и вывод:

user@local:~/user/test/c$ gcc test.c mylib.c -o test
user@local:~/user/test/c$ ./test
Value in main: 42
Value in fn: 84

[EDITED]

Я бы хотел, чтобы NAMEDEFINITION было "42", когда я определяю его в conf.h, затем выведите «42» за два вызова main ().Если он не определен в файле conf.h, его значением по умолчанию будет «84» (выведите «84» в двух вызовах main ().

Ответы [ 3 ]

0 голосов
/ 28 сентября 2018

Я вижу 3 способа сделать это:

1.Сделайте конфигурационный файл обязательной частью вашей библиотеки

mylib.h

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#include "conf.h"
#ifndef NAMEDEFINITION
  #error NAMEDEFINITION hasn't beed defined! Please edit conf.h!
#endif

void fn(); 

2.Определите NAMEDEFINITION с параметром компиляции

Пример:

-D NAMEDEFINITION=42

При таком подходе вы вообще не будете использовать файл conf.h.Недостатком этого метода является то, что вы должны убедиться, что не забудьте включить эту опцию для обеих ваших компиляций .c файла.

3.Включите conf.h с опцией компиляции

Пример:

-include conf.h

Это похоже на метод 2, но вместо непосредственного определения символа вместо этого вы бы принудительно включили conf.h.


Что бы вы ни делали, убедитесь, что в заголовочных файлах есть , включая охранники .(Спасибо @ChristianGibbons)

0 голосов
/ 28 сентября 2018

Объяснение очень простое.

Первый пример (основной) в файле conf.h, который вы определяете.Когда вы включаете mylib.h, он уже определен и не переопределен.Таким образом, значение равно 42

. Во втором примере (fn) вы просто включаете mylib.h и условие #ifndef имеет значение true.

Макросы раскрываются перед компиляцией и действительны только в одном модуле компиляции.,

0 голосов
/ 28 сентября 2018
Value in main: 42

Причина этого заключается в том, что в test.c вы включили conf.h Теперь, даже если вы включите mylib.h, NAMEDEFINITION отображается в test.c и NAMEDEFINITION будет иметь значение 42.ifdef в mylib.h не будет действительным.

Value in fn: 84

В mylib.c вы не включили conf.h.Таким образом, строка #ifndef NAMEDEFINITION будет иметь значение true, а значение NAMEDEFINITION будет равно 84.

Если вы хотите, чтобы значение в fn также печатало 42, вам необходимо включить conf.h в mylib.cили mylib.h

Тогда, если вы закомментируете строку #define NAMEDEFINITION 42 в conf.h, значение 84 будет напечатано оба раза.

...