为什么 C 语言被设计成函数需要先声明才能被使用?

174 天前
 gegeligegeligo

纯粹是因为历史问题吗

1741 次点击
所在节点    问与答
19 条回复
anytk
174 天前
编译和链接,函数声明表明其符号特征,在链接时才能定位精确和一致。
ho121
174 天前
印象当中不是这样。
可以不声明直接调用,编译期间会有个 warning ,运气不好的话链接会失败
NightFlame
174 天前
@ho121 那你记错了
iOCZS
174 天前
怎么隐藏函数呢?
shadowyue
174 天前
施法当然要大声的把招式名称念出来才帅气
proxytoworld
174 天前
确实是历史原因,c99 标准还只能在函数开头声明变量。
proxytoworld
174 天前
@NightFlame 系统库可以这样玩,不引入头文件,直接使用函数也能跑
tianhehechu
174 天前
为了提高编译效率,降低实现复杂度,否则编译时就要遍历整个代码去寻找这个函数。C 标准出来时,机器性能没那么高,编译速度很重要。
darksword21
174 天前
刚开始学的时候感觉还挺符合直觉的….可能就是按直觉设计的吧
hangbale
174 天前
对编译器友好
Mithril
174 天前
是的,纯粹是历史问题。

很久以前这种前置声明可以让你的编译器只遍历一遍编译单元就完成编译。但现在机器性能都很好,一般也都推荐你一个文件不要搞太大。所以你多扫几遍也是能用的。

按照现在的性能来说,就相当于你每个代码文件都几个 G 到十几个 G 那么大,那你这编译器扫几遍你内存就爆炸了。
enchilada2020
174 天前
@proxytoworld 我记得是 C99 以前只能在开头 从 C99 开始可以在任意地方声明了
proxytoworld
174 天前
@enchilada2020 查了一下确实是,c89 只能在开头,
ho121
174 天前
@NightFlame 抱歉,我的印象比较久了。我测试了一下,用以前旧的 C89 标准是可以的。C99 标准不允许了。

两个 c 文件


~ $ cat a.c
int main(){
f();
}
~ $ cat b.c
void f(){}

用 C89 编译,只给了个 warning:

~ $ clang -std=c89 -Wall a.c b.c
a.c:2:5: warning: implicit declaration of function 'f' [-Wimplicit-function-declaration]
2 | f();
| ^
1 warning generated.


用 C99 编译,不通过:

~ $ clang -std=c99 -Wall a.c b.c
a.c:2:5: error: call to undeclared function 'f'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
2 | f();
| ^
1 error generated.
NightFlame
174 天前
@ho121 #14 学习到了
june4
174 天前
要手动同步实现和头文件,不嫌麻烦吗
象 typescript 这种,直接由实现文件自动生成头文件不是更好?
gegeligegeligo
174 天前
@june4 对。。。我也觉得很麻烦,但是要做嵌入式的话,是只能用 c 的
James369
174 天前
这点确实不好用,特别是同一个文件里面,不声明只能调用写在前头的函数
msg7086
174 天前
先声明再使用,是因为没有一个机制去提取声明然后做成索引。
你要搞个通过源代码自动生成头文件的东西,那就也能做到了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/1067051

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX