尽管函数调用的参数数量不正确,但 C 程序编译

Posted

技术标签:

【中文标题】尽管函数调用的参数数量不正确,但 C 程序编译【英文标题】:C Program compiling despite incorrect number of arguments to function call 【发布时间】:2022-01-22 13:44:25 【问题描述】:

我遇到了一个C程序如下:

#include <stdio.h>

int sum1(); //line A

int main()

    int a = 2;
    int b = 3;

    int sum = sum1(a, b);  //line B
    printf("Sum: %d\n", sum);


int sum1(int a, int b, int c) //line C

    int sum = a + b + c;
    printf("%d %d %d\n", a, b, c);
    return sum;

我惊讶地发现程序编译(gcc 版本 7.5.0)并给出以下输出:

2 3 3
Sum: 8

我可以在这个 sn-p 中看到 2 个错误:

    函数声明(A 行)中的参数数量与函数定义(C 行)中的参数数量不同 函数调用(B 行)未指定函数定义(C 行)所需的所有 3 个参数。

用 C++ 编译程序(使用 g++),确实指出了我提到的 2 个错误。

我无法理解 C 是如何忽略此类错误的,但我无法找到任何相关文档。任何有助于理解这一点的帮助将不胜感激。

【问题讨论】:

如果你打开了编译器应该会给你警告,但这不是错误。 C 旨在灵活处理此类事情;带有变量和参数类型的函数是非常合法的,如果操作正确,可以在没有警告的情况下生成。 @LeeDanielCrocker 什么是“错误”?这是一个过时的语言功能,明确不建议使用(自 1999 年以来)。一个体面的编译器会发出“不推荐使用带空括号的函数声明符”或类似的警告,但显然没有一个主流编译器这样做。 【参考方案1】:

这不是错误,但如果您打开它们,编译器肯定会发出警告。开启所有编译器警告并密切关注它们通常是个好主意。

具有不同数量和类型的参数的函数是合法的,在 C 中很常见,如果声明正确,可以在没有警告的情况下执行。

【讨论】:

int sum1(); 声明了一个参数数量及其类型未知的函数,而不是一个必须具有不同数量或不同类型参数的函数。 是的,但是用三个参数定义函数并用两个参数调用它应该会产生警告——在新标准中可能会出错。在老派 C 中,这仍然不是错误。【参考方案2】:

int sum1();forward 声明了一个参数数量及其类型未知的函数,这与您对该函数的定义不冲突。

然而,下面将向前声明一个不接受 任何 参数的函数,该参数 与您的定义相冲突,并且很可能会导致编译错误:

int sum1(void); //line A

第二个问题是当函数需要 3 个参数时,您使用 2 个参数调用 sum1(并且您将其声明为带有未知数量参数的函数)。然后该函数将从堆栈中选择一个int 值的字节(很可能)并使用它。这会破坏堆栈并使您的程序具有未定义的行为

【讨论】:

那么错误 2 呢?我不确定编译器如何为变量“c”赋值。 @Excalibur 抱歉,我错过了那部分,并添加了一个注释。

以上是关于尽管函数调用的参数数量不正确,但 C 程序编译的主要内容,如果未能解决你的问题,请参考以下文章

C语言函数指针定义

带有指针参数的 C++ 函数

C语言函数传递二维数组

extern c

C ++中的求和函数,参数和类型数量未知

C,C+和C++它们有什么区别