【发布时间】:2018-04-03 14:59:52
【问题描述】:
首先,我知道这种编程方式不是好的做法。有关我为什么这样做的解释,请在实际问题之后继续阅读。
当像这样在 C 中声明一个函数时:
int f(n, r) {…}
r 和 n 的类型将默认为 int。编译器可能会生成一个警告,但我们选择忽略它。
现在假设我们调用f,但是,意外或其他原因,遗漏了一个参数:
f(25);
这仍将编译just fine(使用 gcc 和 clang 测试)。但是 gcc 没有关于缺少参数的警告。
所以我的问题是:
- 为什么这不会产生警告(在 gcc 中)或错误?
- 执行时究竟发生了什么?我假设我正在调用未定义的行为,但我仍然希望得到解释。
请注意,当我声明 int f(int n, int r) {…}、gcc 和 clang will compile this 时,它的工作方式不同。
现在,如果您想知道我为什么要这样做,我在玩 Code Golf 并试图缩短我的 code,它使用了递归函数 f(n, r)。我需要一种隐式调用f(n, 0) 的方法,所以我定义了F(n) { return f(n, 0) },这对我来说有点太多字节了。所以我想知道我是否可以省略这个参数。我不能,它仍然可以编译,但不再有效。
在优化此代码时,有人向我指出,我可以在函数末尾省略 return - gcc 也不会对此发出警告。 gcc 是不是太宽容了?
【问题讨论】:
-
您说的是过时的 C 功能,编译器仍支持这些功能以实现向后兼容性。如果没有原型,可以使用任意数量和类型的参数调用函数。但是现在这在严肃的编码中已经没有位置了,所以要获得提示,尤其是打代码,最好在 codegolf.stackexchange.com 上询问?
-
“r 和 n 的类型将默认为 int” - 不在现代严格符合的编译器上。
-
这仍然可以编译得很好 不是在符合任何几十年前的 C 标准的编译器上。
-
“执行时究竟会发生什么?我假设我正在调用未定义的行为,但我仍然希望得到解释”——关于这个措辞的一般建议:这是不可能请求的,或者充其量需要一个月的博客才能涵盖实际上任何事情发生的可能性。
标签: c function parameter-passing compiler-warnings undefined-behavior