在ANSI C前语法中混淆函数调用

我正在处理一些pre-ANSI C语法。 请参阅我在一个条件中有以下函数调用

BPNN *net; // Some more code double val; // Some more code, and then, if (evaluate_performance(net, &val, 0)) { 

但是函数evaluate_performance定义如下( 具有上述条件的函数下面 ):

 evaluate_performance(net, err) BPNN *net; double *err; { 

为什么用两个参数定义evaluate_performance ,但用三个参数调用? ‘0’是什么意思?

顺便说一下,我很确定它没有调用其他地方定义的其他evaluate_performance ; 我已经浏览了所有涉及的文件,我很确定我们应该在这里讨论相同的evaluate_performance

谢谢!

如果你调用一个没有声明原型的函数(就像这里的情况那样),那么编译器会假定它接受任意数量和类型的参数并返回一个int 。 此外, charshort参数被提升为intfloat s被提升为double s(这些被称为默认参数提升 )。

这在新C代码中被认为是不好的做法,原因很明显 – 如果函数没有返回int ,那么错误就可以确保,你阻止编译器检查你传递了正确数量和类型的参数,参数可能得到提升错误。

C99是C标准的最新版本,它从语言中删除了这一function,但实际上,即使在C99模式下运行,许多编译器仍允许使用它们,以实现传统兼容性。

至于额外参数,根据C89标准,它们在技术上是未定义的行为 。 但实际上,它们通常只会被运行时忽略。

代码不正确,但是在某种程度上不需要编译器进行诊断。 (C99编译器会抱怨它。)

旧式函数定义不指定函数期望的参数个数。 对没有可见原型的函数的调用假定返回int并且具有调用隐含的参数的数量和类型(将窄整数类型提升为intunsigned int ,并将float提升为double ) 。 (C99删除了这个;根据C99标准,您的代码无效。)

即使定义在调用之前(旧式定义不提供原型),这也适用。

如果错误地调用此类函数,则行为未定义。 换句话说,程序员有责任正确地提出论点; 编译器不会诊断错误。

这显然不是一个理想的情况; 它可能导致许多未检测到的错误。

这正是ANSI为该语言添加原型的原因。

为什么还在处理旧式函数定义? 你能更新代码以使用原型吗?

就此而言,即使是标准的C编译器也是有点宽容的。 尝试运行以下内容:

 int foo() { printf("here"); } int main() { foo(3,4); return 0; } 

令人惊讶的是,它会"here"输出"here" 。 额外的参数只是被忽略了。 当然,这取决于编译器。

C中不存在重载,因此有2个声明在同一文本中不起作用。

那个必须是一个相当古老的编译器才能在这个上犯错,或者它还没有找到函数的声明!

调用未定义函数时,某些编译器不会发出警告/错误。 这可能就是你遇到的。 我建议你看看编译器的命令行标志,看看是否有一个标志可以用来获取这些警告,因为你可能会发现很多类似的错误(太多的参数可能工作得很好,但也是如此很少有人会利用“未定义”的价值……)

请注意,在printf()中使用省略号时可以执行此操作(添加额外参数):

 printf(const char *format, ...); 

我想这个函数在某个时刻有3个参数,最后一个被删除,因为它没有被使用,而且代码的某些部分没有按照它应该被修正。 我会删除第三个参数,以防堆栈的顺序错误 ,因此无法将正确的参数发送给函数。