int main(int, char const* const*) 格式正确吗?
Posted
技术标签:
【中文标题】int main(int, char const* const*) 格式正确吗?【英文标题】:Is int main(int, char const* const*) well formed? 【发布时间】:2012-06-26 21:25:15 【问题描述】:根据 C++11 标准,以下程序是否是格式良好且可移植的 C++?
int main(int argc, char const* const* argv)
【问题讨论】:
【参考方案1】:没有。在纯可移植 C++ 程序中,argv
参数(如果存在)没有 const
修饰符。
编辑:参见 C++11 草案标准的第 3.6.1.2 节,其中(在我之前的版本中)指出:
实现不应预定义主要功能。这个功能 不得超载。它应该有一个 int 类型的返回类型,但是 否则它的类型是实现定义的。所有实现 应允许以下两个 main 定义:
int main() /*...*/
和
int main(int argc, char* argv[]) /* ... */
【讨论】:
【参考方案2】:取决于您所说的便携式。一个邪恶的 C++ 实现可能会拒绝它,理由是它的签名 int(int,char const*const*)
不同于所需的允许签名之一 int()
和 int(int,char**)
。 (一个邪恶的实现似乎会拒绝auto main(int argc,char* argv[]) -> int
,或者实际上拒绝任何main
的定义,其中body 不是 /* ... */
)
但这不是典型的。我不知道添加 const 会导致调用 main
的问题的任何实现,并且由于 C++11 添加了有关“类似”类型的位,因此在访问 char**
时不会违反严格的别名规则对象通过char const * const *
变量。
因此,虽然符合规范的实现在技术上可能会拒绝它,但我认为它可以移植到您可能希望使用的任何实现中。
【讨论】:
天哪,我没有意识到向合法别名添加类似类型是为了启用其提供的参数和形式参数的类型不匹配的函数;-) 但是是的,它可能只是工作 (TM)。 @SteveJessop 并不打算启用它,实际上通常不会启用它,因为将const
添加到形式参数会影响名称修改。这适用于main
的原因是因为main
通常免于重载(因为无论如何您都不允许重载main)。添加类似类型仅意味着当您将char**
作为char const * const *
访问时,您不会因为违反严格的别名规则而自动获得未定义的行为。在我知道的所有实现上,它在 C++11 之前运行良好,但在技术上它是 UB。现在不应该是UB
您是否碰巧有关于auto main(int argc,char* argv[]) -> int
的来源或标准引用是不同的签名?那么int main(int argc, char** argv)
不也是一个不同的签名吗?
@AntonGolov:我认为标准在这里的措辞是出了名的模糊。它只是说main
的这两个定义 是允许的。它没有说这两个参数列表或这两个签名,这就是为什么你甚至可以开玩笑地争论(就像 bames53 所做的那样)body 必须是/* ... */
。但是,上一句谈到了 main 的 type,而声明为 auto main(int, char**) -> int
的函数的类型与给出的示例之一的类型相同。我想说的是,在对标准的合理解读中,任何与任一示例具有相同签名的 main
都可以。
@bames53:我是在开玩笑,但如果名称修改是唯一剩下的障碍,那么您可以随时使用extern "C"
。然后在另一个 TU 中错误地声明任何函数,并在定义 char const *const
时使用带有 char **
的原型调用它,这与使用 main
的可能性一样。不过我不建议这样做,我认为如果你想要 const-qualified argv
做“正确”的事情就是写 int main(int argc, char **argv) return my_main(argc, argv);
并用 const 定义 my_main
。进行转换,即使类似的类型实际上不需要。以上是关于int main(int, char const* const*) 格式正确吗?的主要内容,如果未能解决你的问题,请参考以下文章
关于int main(int argc, const char * argv[])的理解
套接字编程 connect() 函数错误——“无法将 'main(int, char**)::sockaddr* 转换为 'const sockaddr”
int main(int argc, const char * argv[]) AND 文件输入
以这种格式将 argv 变量传递给 main 的结果 main( int argc, char const * argv )