正如标题所说,我知道导致此错误的原因,但我想知道为什么编译器会在这种情况下提供它。
例如:
的main.c
void test(){
test1();
}
void test1(){
...
}
会给出一个隐式声明警告,因为编译器在读取它的声明之前会到达对test1()的调用,我可以看到这个明显的问题(不知道返回类型等),但为什么不能编译器做一个简单的传递来获取所有函数声明,然后编译删除这些错误的代码?这看起来很简单,我不相信我在其他语言中看到过类似的警告。
在这种情况下,有人知道这个警告是否有特定的目的,我忽略了吗?
答案 0 :(得分:5)
我猜是因为C是一种非常古老的语言,可以追溯到1972年,由于内存和速度限制,这是故意的。
它的定义方式,编译器必须对您的文件进行一次扫描,以了解编译所需的所有内容。不得不做两次通过会更加昂贵,所以这条规则一直存活至今。
另外,正如peoro所说,这条规则使编译器作者的生活更轻松。更不用说IDE的自动完成生活也会让它变得更轻松。
因此,程序编写者的一个小麻烦意味着可以缩短编译器编写者和IDE制造商等人的生活。
哦,你的程序编译速度会更快。当你拥有数百万的代码库时,还不错。
答案 1 :(得分:3)
这就是C的定义方式。
在使用之前有一个声明规则,强制您在使用之前声明符号。
主要是为了让编译器的生活更轻松。
答案 2 :(得分:0)
简短回答:因为C是ooooold。 : - )
长答案:C编译器和链接器是完全独立的。您可能在不同的源文件中定义不同的函数,然后将它们链接在一起。在这种情况下,假设您在单独的库源文件中定义test1
。编译器在编译其他文件之前不会知道test1
,并且它会单独编译另一个文件,因此在编译test
时它无法知道它。因此,你必须告诉它,'是的,其他地方确实有一个test1
,这是它的签名'。这就是为什么你通常包含一个头文件(.h),用于你需要使用的任何其他源文件,在这一个。
答案 3 :(得分:0)
它甚至可能看起来不是这样,但这种方法也节省了你的时间!想象一下,你正在编译一个包含数千个文件的编译单元:在你的场景中,编译器首先必须削减数千个文件然后才能看到“哦,这个函数不存在。中止。”它实现的方式使编译在看到未定义的函数时立即中断。这可以节省您的时间。