27

该标准明确规定main有两个有效(即保证工作)签名;即:

int main();
int main(int, char*[]);

我的问题很简单,以下内容是否合法?

int main(const unsigned int, const char* const* argv);

我的测试说“是”,但我不确定答案,因为我不是main通过更改int为argvunsigned int以及非顶级const-ness 来超载吗?如果我是,那显然是禁止的。

那么,这些修改是否可以保证在符合标准的编译器上工作?

4

7 回答 7

33

C++98 标准在第 3.6.1 节第 2 段中说

实现不应预定义主要功能。该功能不得重载。它的返回类型应该是 type int,否则它的类型是实现定义的。所有实现都应允许以下定义mainint main()int main(int argc, char* argv[])

因此,标准并没有强制要求 env 接受main是可以接受的,但它是允许的。


因为这经常被提及,所以这里是前一段,除了记录它们的行为之外,独立环境免于任何事情:

一个程序应包含一个名为 main 的全局函数,它是程序的指定开始。是否需要独立环境中的程序来定义主要功能是实现定义的。[注意:在独立环境中,启动和终止是由实现定义的;启动包含具有静态存储持续时间的命名空间范围对象的构造函数的执行;终止包含对具有静态存储持续时间的对象执行析构函数。]

于 2009-10-25T18:36:57.223 回答
20

您必须使用符合标准的签名之一才能符合标准。

我完全理解你为什么要按照自己的方式去做。最好的方法是编写你自己的函数myMain()或任何你想要的签名并从 main() 调用它,包括所需的强制转换。

于 2009-10-25T18:52:21.547 回答
2

argv指针不应该是因为const char* const允许程序更改缓冲区。

于 2009-10-25T18:11:42.187 回答
1

据我从阅读标准中可以看出,您不符合标准。但我无法想象一个不允许你这样做的编译器。例如,编译器需要做更多的工作才能专门禁止一种几乎无害且非常模糊的边缘情况。

于 2009-10-25T18:08:50.787 回答
1

如果编译器对main. 毕竟这是一个 C++ 函数。因此,链接器将寻找两个特定的“修饰”。您的定义将有另一个损坏的名称。

请注意,这main是特殊的(不会重载,不可调用)并且可能根本不需要名称修改。

于 2009-10-26T11:15:58.397 回答
0

按照标准,您可能是非法的,但大多数运行时并不真正关心。他们只会推送一个整数 forargc和一个指针 for argv,调用你的main,并希望你能正确解析它们。因此,在您的权限范围内,“保证工作”是有争议的,因为加载程序真的不在乎您将参数声明为什么。

如果它建立,main将被调用。如何解析参数取决于您。我应该澄清一下,这是高度特定于平台的,几乎整个问题也是如此。

说了这么多,为什么呢?

于 2009-10-25T18:12:15.497 回答
0

ISO/IEC 9899:TC3

5.1.2.2.1 节程序启动

程序启动时调用的函数名为 main。实现没有声明这个函数的原型。它应定义为返回类型为 int 且不带参数:

int main(void) { /* ... */ }

或者带有两个参数(这里称为 argc 和 argv,尽管可以使用任何名称,因为它们是声明它们的函数的局部变量):

int main(int argc, char *argv[]) { /* ... */ }

或等价物;9) 或以其他一些实现定义的方式。

于 2010-08-03T05:07:04.977 回答