0

编译器给出警告 warning: second argument of ‘int main(int, std::string*)’ should be ‘char **’ [-Wmain]

当我选择放入

int main(int argv, std::string a[])

代替

int main(int argv, char * argc [])

如果你能想出一个理由,也祈祷一下字符串方法有什么问题。

我的意思是 std::string 是字符表示/字符串表示的后裔,对于 C++,为什么要为 C 样式烦恼?

标准实现真的没有破解吗?

4

3 回答 3

10

原因很简单:语言规则并不强制要求您的表单,并且您使用的实现不通过自己的选择来支持它。

引用标准 3.6.1p2

实现不应预定义主要功能。该功能不得重载。它应该有一个 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 之后添加任何其他(可选)参数。]

编辑:涵盖其他问题:

没有必要“破解”任何东西,因为没有什么可以停止使用将原始 argc 和 argv 获取并按字面意思将其处理为向量的函数或类,或者更好地解析它并将处理后的数据映射到内部变量。我们有很多这样的人,而那些每年创建超过少数 main()-s 的人可能已经使用其中一个或他们自己的。

于 2013-06-30T19:14:00.970 回答
8

解决方法:

 vector<string> args(argv, argv + argc);

 for (auto s: args) 
      cout << s << endl;

std::string并且std::vector是重物。在构造过程中使用动态内存分配。

第二种方法是使用我的 RO 库。下面的代码将围绕数组创建轻量级迭代器范围对象:argv

 auto args = ro::range(argv,argv+argc);

 for (auto s: args) 
      cout << s << endl;
于 2013-06-30T19:36:30.487 回答
1

您已经获得了实现不需要支持它的原因。但是,您的实现不想支持它也是有原因的:

(通常是预编译的)代码调用main传递一个int和一个char**(在某些实现中作为扩展第二个char**;实际上,在许多平台上,它完全获取操作系统已经提供的数据,然后将其传递)。很容易支持忽略尾随参数(通常它们以相反的顺序推送到堆栈中,因此忽略附加参数只是意味着不访问它们,不需要额外的逻辑)。但是,您不能只读出 a char**asstd::string*,因此编译器必须生成额外的代码来支持这个接口。鉴于使用该接口的任何源代码无论如何都是不可移植的,并且很少有人会使用它,并且鉴于原始接口工作得很好,实现该替代接口只会浪费资源。

于 2013-06-30T19:50:44.543 回答