c语言static关键字与关于多个.c文件编译问题

marco0631 2016-12-01 02:42:32
最近在稍微看看c,大学的时候学过不太精。 有个问题关于static关键字的,按照c中static修饰函数,该函数应该限制为仅在当前文件中使用,别的文件无法访问到。当有多个.c文件时候编译时有这样的问题:

test文件:
#include <stdio.h>
#include "test1.c"

int main(int argc, char const *argv[])
{
sayHello();
sayWelcome();
return 0;
}


test1文件:
#include <stdio.h>

static void sayWelcome(void);

void sayHello()
{
printf("hello,");
sayWelcome();
}

static void sayWelcome()
{
printf("welcome\n");
}


以上代码我通过gcc编译(Mac osx默认为clang编译)仅仅指定test.c是通过的并且可以执行,并且能访问static函数。 也就是说static不起效果了。如图:



如果我通过gcc test.c test1.c -o test, 会报重复定义的错,如图:


以上报错原因应该是gcc给定两个文件作为参数时,不需要在test.c中include另一个文件? 我将代码include test1.c的部分去掉。如下:
test.c:
#include <stdio.h>
// #include "test1.c"

int main(int argc, char const *argv[])
{
sayHello();
sayWelcome();
return 0;
}


test1.c:
#include <stdio.h>

static void sayWelcome(void);

void sayHello()
{
printf("hello,");
sayWelcome();
}

static void sayWelcome()
{
printf("welcome\n");
}


结果重复定义的错误ok了。但出现以下新错误:


undefined symbols "_sayWelcome" ... 这是不是static起效果的原因? 那为什么两种方法会有这样的区别? 求大神讲解。

我通过先编译到汇编文件,但两种方式得到的汇编文件完全一样。 菜鸟求解,为什么?? 我想知道编译器内部都做了些什么。
...全文
163 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 2016-12-01
  • 打赏
  • 举报
回复
引用 6 楼 marco_0631 的回复:
[quote=引用 3 楼 paschen 的回复:] .c文件不是用来包含的,需要添加到项目参与编译 static函数只能在该文件中使用,其他文件中可以定义相同名字函数,不会发生冲突 你把static函数放在.c文件里定义
谢谢。我不太清楚c的工作原理,楼上的兄弟说了#include "test1.c"相当于把两个c文件合并在了一起。所以第一种方式相当于把所有内容写在一起所以static看上去不起效果,第二种方式就是相反。还有,static关键字真正起作用的原理是因为编译最后一步链接的时候做的内存限制吗? 怎么限制的?[/quote] .c文件加入工程是作为一个编译单元,如果拿去包含,效果就与.h文件相同,只是添加到其他编译单元参与编译 参看:《程序员的自我修养——链接、装载与库》
marco0631 2016-12-01
  • 打赏
  • 举报
回复
引用 3 楼 paschen 的回复:
.c文件不是用来包含的,需要添加到项目参与编译 static函数只能在该文件中使用,其他文件中可以定义相同名字函数,不会发生冲突 你把static函数放在.c文件里定义
谢谢。我不太清楚c的工作原理,楼上的兄弟说了#include "test1.c"相当于把两个c文件合并在了一起。所以第一种方式相当于把所有内容写在一起所以static看上去不起效果,第二种方式就是相反。还有,static关键字真正起作用的原理是因为编译最后一步链接的时候做的内存限制吗? 怎么限制的?
marco0631 2016-12-01
  • 打赏
  • 举报
回复
引用 2 楼 pengzhixi 的回复:
#include "test1.c" 你看这句吧
好的,谢谢。 不太了解c的工作原理,现在清楚了。
marco0631 2016-12-01
  • 打赏
  • 举报
回复
引用 1 楼 shangyu0801 的回复:
不应该直接包含C文件的。 include的意思是把文件内容直接更当前文件合并!!也就是说,你include了之后其实相当于在一个文件里,static是起作用的。不用怀疑。 按照这个思路在理理看吧。
谢谢。我知道了,也就是第一种include通过gcc编译仅仅相当于一个文件编译成目标文件再和系统库链接成可执行文件。 第二种则是test.o test1.o两个目标文件和系统库文件链接。
paschen 2016-12-01
  • 打赏
  • 举报
回复
.c文件不是用来包含的,需要添加到项目参与编译 static函数只能在该文件中使用,其他文件中可以定义相同名字函数,不会发生冲突 你把static函数放在.c文件里定义
pengzhixi 2016-12-01
  • 打赏
  • 举报
回复
#include "test1.c" 你看这句吧
yu.sang 2016-12-01
  • 打赏
  • 举报
回复
不应该直接包含C文件的。 include的意思是把文件内容直接更当前文件合并!!也就是说,你include了之后其实相当于在一个文件里,static是起作用的。不用怀疑。 按照这个思路在理理看吧。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧