Post by kj501
可以看到,单独把tt.c编译成tt.o和把temp.c编译成temp.o时,编译器都 没有报错。而在将temp.o和tt.o链接在一起时,错误才发生。如果真的象你理解的那样“编译器根据static决定符号可不可以被外部引用”那就应该在编译tt.c时就应该报错。但事实上,这是不可能的。由于编译器是以文件为单位来一个文件一个文件的编译的,gcc在编译tt.c时,它是不知道还有一个temp.c的文件的,它更不会知道foo在temp.c中被定义成static的。tt.c中的foo函数,对于编译器来说,只是一个未定义的符号。它对这个符号的处理,也只能是把它标记成undefined,然后导出到obj文件中,让链接器来处理。
正因为编译器有这种“只见树木不风森林”的特点,全局范围的符号解析只能由链接器完成。当链接器在所有目标文件中都找不到可以全局解析的foo符号时(temp.o的foo是LOCAL的,不能在全局范围内解析),此时才会报错。
Post by Tetris
我们的理解都没有问题,只是表述得不一样而以。在tt.c中foo符号由于没有声明,根据C89它被默认为int foo()。C++就不让了,所有的外部符号都必须有声明,因为有函数重载的问题。C99好像也要求对外部函数有声明。
“编译器根据static决定符号可不可以被外部引用”这句话没有错,tt.c全文都没有出现static这个单词,正如你说的,编译器看到的只是单个文件,那tt.c的编译与static关键字的作用之间应该没有任何关系吧?