我想使用本地.h文件定义在我的lib中使用的相同名称。我的库对此名称有一个默认值定义,但我想使用本地.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
[编辑]
我希望在conf.h中定义NAMEDEFINITION为“ 42”,然后在两个main()调用中打印“ 42”。在conf.h中未定义时,它将是默认值“ 84”(在两个main()调用中打印“ 84”。
答案 0 :(得分:4)
Value in main: 42
这样做的原因是,在test.c
中您已经包含了conf.h
,即使您包含了mylib.h
,NAMEDEFINITION
在test.c
和{{1 }}的值为42。NAMEDEFINITION
中的ifdef
无效。
mylib.h
在Value in fn: 84
中,您没有包括mylib.c
。因此,conf.h
行将为true,#ifndef NAMEDEFINITION
的值为84。
如果您希望fn中的值也显示42,则需要在NAMEDEFINITION
或conf.h
中包含mylib.c
然后,如果将mylib.h
中的行#define NAMEDEFINITION 42
注释掉,则值84将被两次打印。
答案 1 :(得分:2)
我看到您可以通过以下三种方式进行操作:
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();
示例:
-D NAMEDEFINITION=42
使用这种方法,您根本不会使用conf.h文件。此方法的缺点是必须确保记住两个.c文件编译都包含此选项。
示例:
-include conf.h
这与方法2相似,但是您不必直接定义符号,而可以强制包含conf.h。
无论做什么,请确保您的头文件具有include guards。 (感谢@ChristianGibbons)
答案 2 :(得分:1)
解释很简单。
第一个示例(主要) 在conf.h中定义它。当包含mylib.h时,它已经被定义并且没有被重新定义。因此值为42
在第二个示例(fn)中,仅包含mylib.h,并且#ifndef条件为true。
宏在编译之前已展开,并且仅在一个编译单元中有效。