为什么 C 语言被设计成函数需要先声明才能被使用? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gegeligegeligo

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

  •  
  •   gegeligegeligo 2024 年 8 月 22 日 2213 次点击
    这是一个创建于 610 天前的主题,其中的信息可能已经有所发展或是发生改变。

    纯粹是因为历史问题吗

    19 条回复    2024-08-23 06:42:05 +08:00
    anytk
        1
    anytk  
       2024 年 8 月 22 日 via Android
    编译和链接,函数声明表明其符号特征,在链接时才能定位精确和一致。
    ho121
        2
    ho121  
       2024 年 8 月 22 日 via Android
    印象当中不是这样。
    可以不声明直接调用,编译期间会有个 warning ,运气不好的话链接会失败
    89adc64
        3
    89adc64  
       2024 年 8 月 22 日
    @ho121 那你记错了
    iOCZS
        4
    iOCZS  
       2024 年 8 月 22 日
    怎么隐藏函数呢?
    shadowyue
        5
    shadowyue  
       2024 年 8 月 22 日   1
    施法当然要大声的把招式名称念出来才帅气
    proxytoworld
        6
    proxytoworld  
       2024 年 8 月 22 日
    确实是历史原因,c99 标准还只能在函数开头声明变量。
    proxytoworld
        7
    proxytoworld  
       2024 年 8 月 22 日
    @NightFlame 系统库可以这样玩,不引入头文件,直接使用函数也能跑
    tianhehechu
        8
    tianhehechu  
       2024 年 8 月 22 日   2
    为了提高编译效率,降低实现复杂度,否则编译时就要遍历整个代码去寻找这个函数。C 标准出来时,机器性能没那么高,编译速度很重要。
    darksword21
        9
    darksword21  
    PRO
       2024 年 8 月 22 日 via iPhone
    刚开始学的时候感觉还挺符合直觉的….可能就是按直觉设计的吧
    hangbale
        10
    hangbale  
       2024 年 8 月 22 日
    对编译器友好
    Mithril
        11
    Mithril  
       2024 年 8 月 22 日
    是的,纯粹是历史问题。

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

    按照现在的性能来说,就相当于你每个代码文件都几个 G 到十几个 G 那么大,那你这编译器扫几遍你内存就爆炸了。
    KMpAn8Obw1QhPoEP
        12
    KMpAn8Obw1QhPoEP  
       2024 年 8 月 22 日 via Android
    @proxytoworld 我记得是 C99 以前只能在开头 从 C99 开始可以在任意地方声明了
    proxytoworld
        13
    proxytoworld  
       2024 年 8 月 22 日
    @enchilada2020 查了一下确实是,c89 只能在开头,
    ho121
        14
    ho121  
       2024 年 8 月 22 日 via Android   1
    @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.
    89adc64
        15
    89adc64  
       2024 年 8 月 22 日
    @ho121 #14 学习到了
    june4
        16
    june4  
       2024 年 8 月 22 日
    要手动同步实现和头文件,不嫌麻烦吗
    象 typescript 这种,直接由实现文件自动生成头文件不是更好?
    gegeligegeligo
        17
    gegeligegeligo  
    OP
       2024 年 8 月 22 日 via Android
    @june4 对。。。我也觉得很麻烦,但是要做嵌入式的话,是只能用 c 的
    James369
        18
    James369  
       2024 年 8 月 22 日
    这点确实不好用,特别是同一个文件里面,不声明只能调用写在前头的函数
    msg7086
        19
    msg7086  
       2024 年 8 月 23 日
    先声明再使用,是因为没有一个机制去提取声明然后做成索引。
    你要搞个通过源代码自动生成头文件的东西,那就也能做到了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     867 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 63ms UTC 20:57 PVG 04:57 LAX 13:57 JFK 16:57
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86