为什么 main 没有定义 `main(std::vectorargs)`?

发布于 2024-09-14 02:32:41 字数 229 浏览 11 评论 0原文

这个问题只是半开玩笑的。我有时会梦想一个没有裸数组或 C 字符串的世界。

如果您使用的是 C++,那么 main 的首选定义不应该是这样的:

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

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

This question is only half tongue-in-cheek. I sometimes dream of a world without naked arrays or c strings.

If you're using c++, shouldn't the preferred definition of main be something like:

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

?

There are already multiple definitions of main to choose from, why isn't there a version that is in the spirit of C++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

韬韬不绝 2024-09-21 02:32:41

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

在某些情况下,C 代码会在 C++ 编译器中中断,但这种情况相当罕见,并且通常有一个很好的理由来解释为什么需要这种中断。

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

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

当然,在早期,C++ 并没有向量。因此,当向量被添加到语言中时,当然,他们可以更改了main的签名,但随后他们不仅会破坏C代码,还会破坏所有现有的代码C++ 程序。

值得吗?

Because C++ was designed to be (almost) backwards compatible with C code.

There are cases where C code will break in a C++ compiler, but they're fairly rare, and there's generally a good reason for why this breakage is required.

But changing the signature of main, while convenient for us, isn't necessary. For someone porting code from C, it'd just be another thing you had to change, for no particular gain.

Another reason is that std::vector is a library, not a part of the core language. And so, you'd have to #include <vector> in every C++ program.

And of course, in its early years, C++ didn't have a vector. So when the vector was added to the language, sure, they could have changed the signature of main, but then they'd break not just C code, but also every existing C++ program.

Is it worth it?

⊕婉儿 2024-09-21 02:32:41

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

理论上,您应该能够采用 C++ 语言并使用您想要的任何对象、容器等库,无论是标准库还是某些专有库(例如 Qt、MFC)或其他库你自己创造的。定义 main 来接受由标准库中定义的类型组成的参数违背了这一设计目标。

There's another reason besides compatibility with C. In C++, the standard library is meant to be entirely optional. There's nothing about the C++ language itself that forces you to use things from the standard library like std::string and std::vector, and that is entirely by design. In fact, it is by design that you should be able to use some parts of the standard library without having to use others (although this has led to some generally annoying things like std::ifstream and std::ofstream operating on const char* C-style strings rather than on std::string objects).

The theory is that you are supposed to be able to take the C++ language and use whatever library of objects, containers, etc, that you want with it, be it the standard library or some proprietary library (e.g. Qt, MFC), or something that you created yourself. Defining main to accept an argument composed of types defined in the standard library defeats this design goal.

鱼忆七猫命九 2024-09-21 02:32:41

因为它会强制您包含

Because it will force you to include <vector> and <string>.

爱已欠费 2024-09-21 02:32:41

我经常想到的一个问题是,一旦允许复杂类型,最终就会面临在类型的构造函数中抛出异常的风险。而且,按照该语言目前的设计,绝对没有办法捕获这样的异常。如果决定应该捕获此类异常,那么对于委员会和编译器编写者来说,这将需要相当多的工作,这使得这一切比简单地说“allow std::vector”更麻烦;>”。

可能还有其他问题。整个“与运行时不兼容”对我来说似乎是一种转移注意力的东西,因为您现在可以使用宏提供基本相同的功能。但像这样的事情涉及更多。

A concern that keeps coming back to my mind is that once you allow complex types, you end up with the risk of exceptions being thrown in the type's constructor. And, as the language is currently designed, there's absolutely no way for such an exception to be caught. If it were decided that such exceptions should be caught, then that would require considerably more work, both for the committee and compiler writers, making it all somewhat more troublesome than simply saying "allow std::vector<std::string>>".

There might be other issues as well. The whole "incompatible with runtimes" seems like something of a red herring to me, given that you can provide basically the same functionality now with macros. But something like this is rather more involved.

渔村楼浪 2024-09-21 02:32:41

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

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

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

尽管某些开发环境鼓励替换,例如 wmain_tmain.您可以编写自己的编译器/IDE,这将鼓励使用 int vmain(const std::vector& args)

Like @jalf, I sometimes find myself writing

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

But yes, like everyone said, main has to be C-compatible. I see it as an interface to the OS runtime, which is (at least int the systems I use) is written in C.

Although some development environment encourage replacements such as wmain or _tmain. You could write your own compiler/IDE, which would encourage the use of int vmain(const std::vector<std::string>& args).

攒一口袋星星 2024-09-21 02:32:41

因为 C++ 早在 C++ 标准出现之前就已存在,并且很大程度上建立在 C 之上。而且,与原始 ANSI C 标准一样,对现有实践进行编纂是其中的重要组成部分。

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

即使是已经经历了多次迭代的 ISO C,仍然非常非常重视向后兼容性。

Because C++ was in existence long before the C++ standard was, and built heavily on C. And, like the original ANSI C standard, codifying existing practice was an important part of it.

There's no point in changing something that works, especially if it will break a whole lot of existing code.

Even ISO C, which has been through quite a few iterations, still takes backwards compatibility very seriously.

Smile简单爱 2024-09-21 02:32:41

基本上,为了保持与 C 的兼容性。如果我们放弃这一点,main() 将被移动到一个类中。

Basically, to remain compatable with C. If we were to give up that, main() would be moved into a class.

戒ㄋ 2024-09-21 02:32:41

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::vectorargv)除非内存布局恰好在便携式设备中神奇地兼容方式。运行时将使用错误的参数调用 main() 并失败。没有简单的方法可以解决这个问题。

相反,只要 main() 不是 extern "C",运行时就可以按顺序尝试各种受支持的符号,直到找到一个。我想象 main() 默认情况下是 extern "C" ,并且您不能重载 extern "C" 函数。

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

The multiple definitions of main() aren't really multiple definitions. There are three:

  • int main(void) (C99)
  • int main(int argc, char *argv[]) (C99)
  • int main(int argc, char *argv[], char *envp[]) (POSIX, I think)

But in POSIX, you only really get the third. The fact that you can call a function with extra arguments is down to the C calling convention.

You can't have extern "C" int main(std::vector<std::string> argv) unless the memory layout happens to be magically compatible in a portable way. The runtime will call main() with the wrong arguments and fail. There's no easy way around this.

Instead, provided main() wasn't extern "C", the runtime could try the various supported symbols in order until it found one. I imagine main() is extern "C" by default, and that you can't overload extern "C" functions.

For more fun, void main(void).

失眠症患者 2024-09-21 02:32:41

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

C++ 被设计为向后兼容 C,并且 std::vector 包含在仅包含在 C++ 中的库中。

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

我能想到的最多的理由就是这个,欢迎批评指正。

I'll try explain in the best possible sentence.

C++ was designed to be backward compatible with C and std::vector was included in a library that only got included in C++.

Also, C++ and C programs were designed to run in shells or command lines (windows, linux, mac) and OS pass arguments to a program as an array of String. How would an OS really translate vectors?

That's the most reason I can think of, feel free to criticize it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文