我正在尝试(重新)定义我已设置的配置宏。下面是我想做的一个示例:
/* inc/foo.h */
#ifndef FOO_H
#define FOO_H
#include <stdio.h>
#ifndef FOO_CONF_MACRO
#define FOO_CONF_MACRO 0
#endif
void foo(void);
#endif
/* src/foo.c */
#include "foo.h"
void foo(void)
{
printf("%d\n", FOO_CONF_MACRO);
}
/* inc/bar.h */
#ifndef BAR_H
#define BAR_H
#include <stdio.h>
#define FOO_CONF_MACRO 3
#include "foo.h"
void bar(void);
#endif
/* src/bar.c */
#include "bar.h"
void bar(void)
{
printf("Bar!\n");
}
/* app/main.c */
#include "bar.h"
#ifndef FOO_CONF_MACRO
#undef FOO_CONF_MACRO
#endif
#define FOO_CONF_MACRO 18
#include "foo.h"
int main()
{
foo();
bar();
return 0;
}
我希望编译所有文件并运行main.c
后得到以下输出:
18
Bar!
然而,我实际观察到的是:
0
Bar!
或者,如果我没有在main.c
中重新定义宏,我会期望:
3
Bar!
我发现this question非常相似。This answer特别让人觉得这取决于文件编译和链接的顺序。我同意OP的观点,尽管我已经多次看到这个构造在你自己编译的代码中实现配置宏。那么这真的取决于编译和链接的顺序吗?如果是的话,获得所需输出的正确顺序是什么?
目前,我在makefile中有以下代码:
### app/Makefile
INCLUDES = $(wildcard ../inc/*.h) #/**/
CFLAGS := -O2 -Wall -Wextra -std=gnu99 -I. -I../inc
### build targets
all: main
### modules
## submodules
obj:
mkdir -p obj
obj/%.o: ../src/%.c $(INCLUDES) | obj
gcc -c $(CFLAGS)
## main program
obj/main.o main.c $(INCLUDES) | obj
gcc -c $(CFLAGS) $< -o $@
main: obj/main.o obj/bar.o obj/foo.o
gcc $< obj/bar.o obj/foo.o -o $@
当我观察make
的输出时,似乎先生成了main.o
,然后是bar.o
,最后是foo.o
。
1条答案
按热度按时间e37o9pze1#
源文件(
foo.c
,bar.c
和main.c
)连同它们包含的 * 头文件 * 是三个独立的翻译单元,彼此没有任何联系。头文件与任何名称相似的源文件实际上是无关的。如果您直接在源文件中更改一个翻译单元中的宏,那么其他翻译单元将不会知道它。
如果您更改了头文件中的宏,则只有包含头文件的翻译单元会知道它。
因为
foo.c
只包含foo.h
,所以它只知道头文件中的宏。