程序不应该按照“C 常见问题”运行,但它可以运行

Program should not work as per `C faq` but it works

我刚浏览 c-faq,就看到了 this 页面。我声明以下程序将有一个核心转储:

struct list {
    char *item;
    struct list *next;
}

/* Here is the main program. */

main(argc, argv)
{}

他们告诉核心转储发生的原因是:

A missing semicolon at the end of the structure declaration causes main to be declared as returning a structure. (The connection is hard to see because of the intervening comment.) Since structure-valued functions are usually implemented by adding a hidden return pointer (see question 2.9), the generated code for main() tries to accept three arguments, although only two are passed (in this case, by the C start-up code). See also questions 10.9 and 16.4.

虽然,当我 运行 这个程序在线 here 时,它运行得很好并且程序 运行 直到结束。另外,当我使用 gcc 编译这个程序时,我没有收到任何警告。

我很惊讶,因为程序应该 运行 到最后才结束。有人能告诉我为什么这个程序有效吗?如果是正确的,为什么会提到程序无法运行(有没有可能崩溃?)。

注意:请不要post评论使用int main因为我只是复制粘贴代码,实际上,我使用正确的方法。

这是对 C FAQ 的误读。

C FAQ 解释了代码不正确的原因,但并未说明代码一定会崩溃。以下是您引用的部分内容:

Since structure-valued functions are usually implemented by adding a hidden return pointer...

我已经强调了。 C FAQ 解释了代码 可能 崩溃的原因。在这两种情况下,代码都不正确。 (理论上,该行为可能是 实现定义的, 但您的 C 实现极不可能定义在这种情况下发生的情况。)

在许多系统 (ABI) 上,如果结构足够小,return 结构的函数将使用寄存器作为 return 值。我不知道常见的 x64 ABI 的限制是多少,但是两个词(两个指针)相当小。

根据标准,该程序似乎不违法。 让我们看看首先清理的程序:

struct list {
    char *item;
    struct list *next;
} main(argc, argv){}

好的,所以我们将 main 声明为返回一个结构列表。 现在让我们看看 main 根据 ISO 9899:2011 的有效声明 (C11)虽然C99大体相同

It shall be defined with a return type of int and with no parameters or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared). or in some other implementation-defined manner.

(略有删节) 在我看来,这因此完全属于 "some other implementation-defined manner" 的第三个定义,这意味着它属于实现定义行为的领域。

因此,这根本不是 C 的问题,而是取决于正在使用的编译器,因此与 C 常见问题解答在很大程度上无关。您需要查看编译器的文档以了解其定义的用途(如果有的话)。

很可能您的编译器根本没有定义它,在这种情况下它是未定义的,因此可能导致任何行为,包括看似正常工作或崩溃。