【发布时间】:2020-11-11 03:57:10
【问题描述】:
-
我知道“不属于该函数定义的函数声明符中的空列表指定不提供有关参数数量或类型的信息 em>„[1]:
// No information about the parameters is supplied. int foo(); -
我知道“一个函数声明器中的一个空列表,它是该函数定义的一部分,它指定该函数没有参数„[2 ].
// In this case the foo() function has no parameters. int foo() { // ... } -
我知道“
void类型的未命名参数的特殊情况作为列表中的唯一项指定 函数没有参数„[3]:// foo() has no parameters. int foo(void); // bar() has no parameters. int bar(void) { // ... };
所以这里有一些问题:
-
int main() { /* ... */ }合法吗?该标准规定[4]程序启动时调用的函数名为
main。实现没有声明这个函数的原型。它应使用int的返回类型定义且不带参数:int main(void) { /* ... */ }或带有两个参数(此处称为
argc和argv,尽管可以使用任何名称,因为它们是声明它们的函数的本地名称):int main(int argc, char *argv[]) { /* ... */ }或等价物;或以其他一些实现定义的方式。
那么,
int main() { /* ... */ }是否等同于int main(void) { /*... */ }? -
为什么 GCC 允许将参数传递给没有参数的函数?
int foo(); int bar() { return 42; } int main(void) { // Should be OK. foo(13); // Should give a compile-time error. bar(1, 12); }但我实际上可以用
gcc version 10.1.0 (GCC)编译程序:gcc -std=c17 -Werror -c test.c。
看过一些相关的问题,比如What are the valid signatures for C's main() function?,但是没有考虑到下面的标准条款[2]:
作为该函数定义一部分的函数声明器中的空列表指定该函数没有参数。
那么,我对这个条款的理解正确吗?
- ISO/IEC 9899:2017 § 6.7.6.3 / 14。
- ISO/IEC 9899:2017 § 6.7.6.3 / 14。
- ISO/IEC 9899:2017 § 6.7.6.3 / 10。
- ISO/IEC 9899:2017 § 5.1.2.2.1 / 1。
【问题讨论】:
-
C(和 C 编译器)的基本理念是“程序员知道他们在做什么”,如果他们做了什么傻 UB允许任何事情发生。所以写
int main() { ... }是愚蠢,但是,一般来说,编译器无论如何都会做正确的事情而不进入UB领域 -
@EricPostpischil gcc 将在将来的版本中删除它,因为有人会为此付费。 (它位于列表的最后,因为每次更改都需要花钱,而 IMO 这是最不重要的问题之一)。
-
已发布的标准草案似乎没有您引用的部分或措辞。
-
我已经dupehammer重新打开了这个问题,因为我没有看到OP在stackoverflow.com/questions/13950642/…上实际提出的问题的答案。 stackoverflow.com/questions/41803937/func-vs-funcvoid-in-c99 和/或 stackoverflow.com/questions/29190986/… 至少有一个答案;使用 dupehammer 重新打开问题后,IIRC,我无法将其作为其中之一的副本重新关闭。
标签: c language-lawyer signature function-prototypes