C和C++中没有定义的主函数function main

5

为什么这段代码在C语言中可以编译成功,而在C++中会报错?

int main;

在托管环境中,它是否符合标准?你能引用标准吗?

我已经使用gcc进行了测试。


1
@SparKot C++ 不是强类型语言。它具有弱静态类型约束。 - Bernd Elkemann
4个回答

9
为什么这段代码在C中编译成功,在C++中会产生错误?
因为C++会对函数名进行“名称修饰”。在实际的实现过程中,连接器会寻找一个名为"main"的符号(或其变体,比如苹果平台上的"_main"),在C中可以是"main()"函数或者是一个外部存储的名为"main"的变量。通常C实现(编译器,工具链)在链接器级别上不区分变量和函数,因此提供一个名为"main()"的符号即可,不论是变量还是函数,便足以实现程序的链接。但是在托管环境下,根据标准规定,必须要实现"main()"函数来生成合格的可执行文件。
而在C++中,通常使用名称修饰(以实现C++的功能,如函数重载),这意味着编译器会根据符号的类型、是否为函数、带有不同签名的函数以及其他情况,对生成的符号进行命名。因此,连接器基本上无法找到对应于期望的"int main(int, char *[])"函数的符号,并将发出错误消息。
它符合标准吗?
不定义"main()"函数是不符合标准的(参见第一部分)。据我所知,在C++中同时拥有名为"main"的变量和"main"函数是有效的,但这绝对是一种不好的做法。
能引用标准吗?
可以,请看以下摘录(重点在于强调):
C++98,第3.6.1段:
程序“应该包括”一个名为"main()"的全局函数,它是程序的指定起始点。在独立环境中,程序是否需要定义"main()"函数是“实现定义”的。
C99,第5.1.2.2.1段:
5.1.2.2.1 程序启动
1 程序启动时调用的函数名为main,实现对此函数不声明原型。

1
看起来不定义main函数并不一定是错误的,尽管这可能非常不寻常。在自由环境中,程序是否需要定义main函数是实现定义的。(参见3.6.1.1) - Tom Kerr
@H2CO3:讲得很清楚,但最后一句话能否再详细解释一下?赞一个。 - Omkant
1
@NikitaTrophimov 我已经将这个添加到你的问题中了。这是一个非常好的问题,点赞+1。 - user529758
1
@NikitaTrophimov 这段代码在符合托管的C++环境中应该不能编译,且在符合规范的C环境中可能编译,但是,生成的程序将不符合规范。 - user529758
2
@NikitaTrophimov 这不取决于标准,而是取决于实现。如果程序没有将 main() 实现为函数,则它不符合规范,因此标准对其没有任何要求,因此它本质上会引发 UB,因此它不必运行。但是,它可能会基于实际和常见的实现细节进行编译,但这与我在答案中解释的相同。 - user529758
显示剩余9条评论

4
ISO/IEC 14882:1998(E)(又称 C++98)起,3.6.1 主函数
一个实现不应该预定义main函数。这个函数不应该被重载。它应该有一个返回类型为int,但是除此之外,其类型是由实现定义的。所有实现都应该允许以下两种main定义:int main() { /* ... */ }int main(int argc, char* argv[]) { /* ... */ }在后一种形式中,argc应该是从程序运行环境中传递给程序的参数数量。如果argc非零,则这些参数应作为指向以null结尾的多字节字符串(NTMBS)的初始字符的指针通过argv[0]到argv[argc-1]提供,并且argv[0]应该是表示用于调用程序的名称或""的NTMBS的初始字符的指针。argc的值应该是非负数。argv[argc]的值应该是0. [注意:建议在argv之后添加任何进一步的(可选)参数。]

程序中不得使用函数main(3.2)。函数main的连接(3.5)为3,实现定义。声明main为内联或静态的程序是非法的。否则,名称main未保留。[示例:成员函数、类和枚举可以被称为main,其他命名空间中的实体也可以这样。]


int main; 不符合上述规定(“所有实现都应允许以下两种main的定义”,“程序内不得使用函数main(3.2)”)。


还有什么?我不知道你的意思。是的,我以前看过这个引用。 - FrozenHeart
@NikitaTrophimov 你可能想看一下我的答案。同时,对于Brian:仅仅引用标准而没有任何解释是不太有建设性的。 - user529758
确实,你的回答更清晰了。我添加了一些解释。 - Brian Cain
1
@H2CO3: 鉴于非专业人士甚至很难找到标准的相关部分(有时甚至是标准文本本身),我认为引用标准,特别是如果使用正确的引文,至少是一个高质量的答案。 - R.. GitHub STOP HELPING ICE
@R.. 请耐心等待!我马上会引用标准。 我只是在寻找正确的引用。另外,没有解释的引语可能不是最好的解决方案,正如你所提到的原因一样。 - user529758
1
我并不是在抱怨你的回答,只是想说(也许这应该放在元站上,但无论如何)我认为在 Stack Overflow 上,一个来自相关标准的适当引用至少是一个高于平均水平/高质量的答案。当然,评论/解释可以使其更好,而没有引用的良好解释性答案在许多情况下也可以非常好,除非问题明确要求引用。 - R.. GitHub STOP HELPING ICE

1
我认为,我找到了一个。虽然不是解决方案,但需要记住的一点是,如果您使用以下命令:

gcc -Wall -Werror <file.c>

您将会得到警告被视为错误:

main is usually a function name

最好使用-Wall编译,这样您就可以看到所有的警告信息。

1

是的,它是有效的。

它声明了一个名为main的整数。


但是main函数在哪里?为什么我需要在C++中定义main函数? - FrozenHeart
@KingsIndian 嗯,不完全是这样。 - user529758
@H2CO3,既然C++不允许调用main()函数,你认为一个名为main的变量有什么问题(除了容易混淆)? - P.P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接