为什么有些人在一个函数中声明了extern函数?

时间:2016-08-12 09:06:05

标签: c function extern

我需要维护一些其他人编写的代码。我只是遇到了在一个函数内声明并在别处定义的许多函数。 例如:

int func(){
    ...
    extern func1();
    extern func2();
    ...

}

为什么他们声明和定义这样的函数?为什么他们不在外面声明函数?有什么优势?

3 个答案:

答案 0 :(得分:6)

这是一种非常危险的做法 - 无法保证原型与实际功能匹配,如果它不匹配,各种事情都可能出错。特别是实际实现这些功能的代码不会看到这个声明,这使它变得危险。

执行此操作的正确方法是两个函数的作者将其声明放入头文件中,使用它们的文件应包含该头文件。通常,每个C函数都应该是静态的,或者应该在头文件中声明。

如果代码是这样编写的,那么它是出于懒惰,可能是出于为未来的开发人员设置陷阱的愿望。您还可以看到声明使用过时的样式:extern func1()表示func1返回一个int(作为默认值),并且它需要一个未知但固定数量的参数。所以你(和编译器)甚至不知道如何调用它。

我们假设该功能已实现为

int func1 (int arg)

并且实施者决定将其更改为

void func1 (int arg, int* result)

通过指针返回值,而不是函数结果。奇怪的声明将确保编译器没有机会检测到这一点,并且在更改之后调用func1很可能会崩溃,或者更糟糕的是在应用程序的某处覆盖随机int。这是一场等待发生的灾难。如果您在应用程序中看到这样的代码,请立即修复它。

答案 1 :(得分:1)

唯一的目的是减少外部声明可见的范围。

答案 2 :(得分:1)

发布的示例实际上是不正确的,原型应该有一个返回类型:

int func(void) {
    extern int func1();
    return func1();
}

int func2(void) {
    return func1();  // declaration out of scope
}

这种非常糟糕的做法允许func1的声明属于函数体func的本地。在func1函数结束后,func的声明没有任何效果。在实践中,现代编译器会跟踪这些可疑的声明和抱怨。

这是不好的做法,因为无法验证声明与实际定义的一致性。将声明放置在使用文件中包含的头文件中以及定义该函数的文件中是正确的方法。