5

为什么这段代码在 C 中编译成功并且在 C++ 中会给你一个错误?

int main;

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

我已经用 gcc 对其进行了测试。

4

4 回答 4

9

为什么这段代码在 C 中编译成功并且在 C++ 中会给你一个错误?

由于 C++ 名称修改。基本上,在所有实际实现中,链接器都会查找一个名为(或它的变体,我在 Apple 平台上看到过)的符号- 在 C 中,它可以是函数或命名的外部存储变量- 关键是通常C 实现(编译器、工具链)在链接器级别不区分变量和函数,这就是为什么提供一个符号,无论是变量还是函数,命名似乎就足够了。事实上,在托管环境中,根据标准,生成的程序(可执行文件)将不符合要求,因为在那里,需要实现该功能main_mainmain() mainmain() main()

在 C++ 中,通常使用名称修饰(为了实现 C++ 的功能,例如函数重载),这意味着编译器根据其类型在可执行文件中以不同的方式命名生成的符号,如果它是一个函数,变量、具有不同签名的函数以及其他情况。所以链接器基本上不会找到预期int main(int, char *[])函数对应的符号,会发出错误信息。

是否符合标准?

不定义main()函数不是(见第一部分)。据我所知,main与主函数一起命名的变量是有效的 C++,但这肯定是不好的做法。

你能引用标准吗?

是的,请(强调我的):

C++ 98,第 3.6.1 段:

一个程序应包含一个名为 的全局函数main(),它是程序的指定开始。是否需要独立环境中的程序来定义功能是实现定义的。main()

C99,第 5.1.2.2.1 段

5.1.2.2.1 程序启动

1 程序启动时调用的函数名为main。实现没有声明这个函数的原型。一世

于 2012-10-26T20:44:04.243 回答
4

来自ISO/IEC 14882:1998(E)(又名 C++98),3.6.1 主要功能

实现不应预定义主要功能。该功能不得重载。它应该 2 具有 int 类型的返回类型,否则它的类型是实现定义的。所有实现都应允许以下两种 main 定义: int main() { /* ... */ }int main(int argc, char* argv[]) { /* ... */ } 在后一种形式中,argc 应是从程序运行的环境传递给程序的参数数量。如果 argc 不为零,则这些参数应通过 argv[0] 提供
argv[argc-1] 作为指向空终止多字节字符串 (NTMBS) (17.3.2.1.3.2) 的初始字符的指针,并且 argv[0] 应是指向 NTMBS 的初始字符的指针,该名称表示用于调用程序或“”。argc 的值应为非负数。argv[argc] 的值应为 0。 [注意:建议在
argv 之后添加任何其他(可选)参数。]


函数 main 不得在程序中使用(3.2)。main 的链接(3.5)是 3 实现定义的。将 main 声明为 inline 或 static 的程序是格式错误的。名称 main 没有保留。[示例:成员函数、类和枚举可以称为 main,其他命名空间中的实体也可以。]


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

于 2012-10-26T20:40:49.127 回答
1

是的,它是有效的。

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

于 2012-10-26T20:39:08.080 回答
1

我想,我找到了一个。这不是一个解决方案,但要记住如果你使用

gcc -Wall -Werror <file.c>

您将收到警告被视为错误:

main is usually a function name

所以最好编译,-Wall这样你也可以看到所有的警告

于 2012-10-26T21:04:22.323 回答