最近在看代码的过程中,发现一种新玩法,就是在一个*.c文件中,直接include另一个 *.c 文件,以往都是include一个 *.h文件。这个脑洞大开,神奇!随之而来的有两个问题:
Q1. 这么写代码有什么效果?
Q2. 想知道原作者为什么这么写代码 ?
先来看第一个问题,这么写代码有什么效果,准备两个源文件如下:
.
├── driver.c
└── main.c
driver.c 文件内容如下:
void readDriver(void)
{
int i = 0;
i++;
}
main.c 文件内容如下:
#include "driver.c"
int main(void)
{
readDriver();
return 0;
}
运行以下gcc命令,获取宏定义,include文件展开后的效果
root@localhost:~/testWorkSpace/C/include$ gcc -E -P main.c
void readDriver(void)
{
int i = 0;
i++;
}
int main(void)
{
readDriver();
return 0;
}
从实验结果可知,“main.c”文件中#include "driver.c"语句,相当于将文件“driver.c”的内容完全”复制“到了main.c文件中。
使用此种方式有上述优点,还有一个限制,就是两个文件不能同时参加编译,否则,会在链接过程中,出现函数多处定义的错误,造成链接失败。原因显而易见,函数”readDriver()"在两个文件中定义了两次。
root@localhost:~/testWorkSpace/C/include$ cmake --build ./build/
Scanning dependencies of target include
[ 33%] Building C object CMakeFiles/include.dir/main.c.o
[ 66%] Building C object CMakeFiles/include.dir/driver.c.o
[100%] Linking C executable include
CMakeFiles/include.dir/driver.c.o: In function `readDriver':
driver.c:(.text+0x0): multiple definition of `readDriver'
CMakeFiles/include.dir/main.c.o:main.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
CMakeFiles/include.dir/build.make:98: recipe for target 'include' failed
make[2]: *** [include] Error 1
CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/include.dir/all' failed
make[1]: *** [CMakeFiles/include.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
从网上找了一些相关的资料,目前,知道这么写有以下优点:
需要某个功能,在源文件中包含相关的源文件。
在测试代码文件中直接引入目标测试函数,而非到链接阶段,才引入目标测试函数。