为什么主要定义不是`main(std :: vector <std :: string> args)`?</std :: string>

时间:2010-08-13 14:53:20

标签: c++ vector coding-style command-line-arguments idioms

这个问题只是半眯着眼睛。我有时会梦想没有裸阵或c弦的世界。

如果你正在使用c ++,那么main的首选定义不应该是:

int main(std::vector<std::string> args)

已经有多个main的定义可供选择,为什么没有一个符合C ++精神的版本?

9 个答案:

答案 0 :(得分:11)

因为C ++被设计为(几乎)向后兼容C代码。

在某些情况下,C代码会在C ++编译器中中断,但它们相当罕见,并且通常有充分的理由说明为什么需要这种破坏。

但是改变main的签名虽然对我们来说很方便,但必然。对于从C移植代码的人来说,这只是你必须改变的另一件事,没有特别的好处。

另一个原因是std::vector是一个库,而不是核心语言的一部分。因此,您必须在每个 C ++程序中#include <vector>

当然,在早期,C ++并没有拥有一个向量。因此,当向量添加到语言中时,确定,可以更改main的签名,但是它们不仅会破坏C代码,还会破坏每个现有的C ++程序。

值得吗?

答案 1 :(得分:10)

除了与C兼容之外,还有另一个原因。在C ++中,标准库应该是完全可选的。没有任何关于C ++语言本身会迫使您使用标准库中的内容,如std::stringstd::vector,这完全是设计上的。实际上,按照设计,您应该能够使用标准库的某些部分而不必使用其他部分(尽管这会导致一些通常令人烦恼的事情,例如std::ifstreamstd::ofstream在{ {1}} C风格的字符串而不是const char*个对象)。

理论上,您应该能够使用C ++语言并使用您想要的任何对象库,容器等,无论是标准库还是某些专有库(例如Qt,MFC)或者你自己创造的东西。定义std::string以接受由标准库中定义的类型组成的参数会违背此设计目标。

答案 2 :(得分:5)

因为它会强制您加入<vector><string>

答案 3 :(得分:4)

像@jalf一样,我有时会发现自己在写

int main(int argc, char** argv) {
    std::vector<std::string> args(argv, argv+argc);

但是,就像所有人都说的那样,main必须与C兼容。我将其视为OS运行时的接口,它(至少在我使用的系统中)是用C语言编写的。

虽然某些开发环境鼓励替换wmain_tmain。您可以编写自己的编译器/ IDE,这将鼓励使用int vmain(const std::vector<std::string>& args)

答案 4 :(得分:4)

一个让我想起的问题是,一旦你允许复杂的类型,你最终会在类型的构造函数中抛出异常的风险。并且,由于语言目前正在设计中,因此绝对无法捕获此类异常。如果决定应该捕获这样的异常,那么对于委员会和编译器编写者来说,这将需要更多的工作,使得比简单地说“允许std::vector<std::string>>”更麻烦。

也可能存在其他问题。考虑到你现在可以用宏提供基本相同的功能,整个“与运行时不兼容”似乎对我来说是一个红色的鲱鱼。但是这样的事情更为复杂。

答案 5 :(得分:3)

因为C ++早在C ++标准出现之前就存在了,并且很大程度上依赖于C语言。并且,与原始的ANSI C标准一样,编纂现有实践是其中的一个重要部分。

改变可行的东西是没有意义的,特别是如果它会破坏大量现有代码。

即使是经过相当多次迭代的ISO C,仍然会认真地反向兼容非常

答案 6 :(得分:2)

基本上,要与C保持一致。如果我们放弃它,main()将被移动到一个类中。

答案 7 :(得分:2)

main()的多个定义实际上不是多个定义。有三个:

  • int main(void)(C99)
  • int main(int argc, char *argv[])(C99)
  • int main(int argc, char *argv[], char *envp[])(POSIX,我认为)

但是在POSIX中,你只有真正获得第三个。您可以使用额外参数调用函数的事实取决于C调用约定。

不能拥有extern "C" int main(std::vector<std::string> argv),除非内存布局恰好以便携方式神奇地兼容。运行时将使用错误的参数调用main()并失败。这没有简单的方法。

相反,如果main()不是 extern "C",运行时可以按顺序尝试各种支持的符号,直到找到它为止。我想main()默认为extern "C",并且你不能重载extern "C"函数。

为了更多乐趣,void main(void)

答案 8 :(得分:1)

我会尝试用最好的句子解释。

C ++旨在向后兼容C,而std::vector包含在只包含在C ++中的库中。

此外,C ++和C程序设计为在shell或命令行(windows,linux,mac)中运行,OS将参数作为String数组传递给程序。操作系统如何真正翻译矢量?

这是我能想到的最重要的原因,请随意批评它。