“ int main(vooid)”?这是如何运作的?


135

最近,我不得不输入一个小型的C测试程序,在此过程中,我偶然通过使用vooid而不是来在主要功能中犯了一个拼写错误void

但是它仍然有效。

将其缩减为最小的完整版本,最终得到:

int main (vooid) {
    return 42;
}

但这确实编译(gcc -Wall -o myprog myprog.c),并在运行时,它会返回42。

此有效代码到底有多正确?


这是一个从我的bash外壳剪切并粘贴的成绩单,以显示我在做什么:

pax$ cat qq.c
int main (vooid) {
    return 42;
}

pax$ rm qq ; gcc -Wall -o qq qq.c ; ./qq

pax$ echo $?
42

通过使用单个int参数定义main ,可以调用Undefined Behavior。什么都可能发生:)
pmg 2011年

9
实际上,我不确定UB @pmg。ISO特别允许main从标准两个规范的其他可能性。对于可移植性,您应该使用这两种方法之一,但是我认为UB在这里不适用。
paxdiablo 2011年

嗯:在托管环境中,main必须具有以下两种规范形式(2.1.2.2)之一。但是@pax是正确的,在独立的环境中,标识符main绝非特别:如果用作函数,则标识符可以是任何类型,并且可以具有任意数量的任何类型的参数。
2011年

2
在C99中,独立性是完全实现的定义。对于托管,第5.1.2.2.1节在末尾“或以其他一些实现定义的方式”声明,因此它至少需要两种规范形式,但也可以具有其他规范形式(这将使UNIXy int main (int argc, char *argv[], char *envp[]);符合标准) )。
paxdiablo 2011年

Answers:


220

它只是使用“旧式”函数声明语法。您将隐式声明一个int名为的参数vooid


2
这似乎是事实。如果添加“ vooid = 42;返回vooid;” 主,你也可以得到42的返回值
杰夫·埃姆斯

43
阿尔高,你是对的。如果加上-std=c99,我得到qq.c:1: warning: type of 'vooid' defaults to 'int'
paxdiablo 2011年

70

这是有效的代码,因为myprog.c包含:

int main (vooid) // vooid is of type int, allowed, and an alias for argc
{     
  return 42; // The answer to the Ultimate Question
} 

vooid包含一个加上传递的参数数量(即argc)。因此,实际上您要做的就是重命名argcvooid


11
如果您做“回声”;相反,它确实给出了1 + num。args。
杰夫·艾姆斯

6
@Jeff,该程序的名称被认为是争论,因此+1
Martin Beckett

23

在C语言中,函数参数的默认类型为int。因此,您的程序将单词vooid视为int main(int vooid),这是完全有效的代码。


20

它只是gcc -std=c89 -Wall -o qq qq.cgcc -std=gnu89 -Wall -o qq qq.c不会发出警告。所有其他标准发出有关隐式类型的警告intvooid

int main(chart)行为与相同int main (vooid)

return vooid; 返回命令行参数的数量。

我在Debian测试系统上使用gcc 4.4.5进行了测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.