【问题标题】:how casting of return value of main() function works?main() 函数的返回值的转换如何工作?
【发布时间】:2011-04-25 11:42:10
【问题描述】:

我正在使用 Visual Studio 2008。 对于下面的代码

double main()
{
}

我得到错误:

错误 C3874:'main' 的返回类型 应该是“int”而不是“double”

但是如果我使用下面的代码

char main()
{
}

没有错误。 运行退出后输出窗口显示

程序'[5856] test2.exe: Native' 已退出,代码为 -858993664 (0xcccccc00)。

问题:编译器是否正在从默认返回值零(整数)隐式转换为字符?

代码 0xcccccc00 是如何生成的?

看起来该代码中的最后一个字节似乎是实际的返回值。为什么0xcccccc来了?

【问题讨论】:

  • 不管你的问题是什么,都不要改变main的返回值。只是不要这样做!
  • 这真的是作业吗?
  • @John:是的。尝试了解更多信息。
  • 如果您让 main() 返回其他类型而不是 int,则行为未指定。这意味着每个编译器都可能产生不同的输出,甚至如您所见的错误。
  • -1 表示又一个无用的“为什么这有效?”/“为什么这不会给出错误?”对于未定义的行为。

标签: c++ c


【解决方案1】:

按照 C++ 标准,正确的做法是:

int main()
{
...
}

不要将返回类型更改为其他任何内容,否则您的代码将不是 C++,而您只是在使用编译器特定的功能。您示例中的那些 ccccc 值只是返回的未初始化字节(C 分配器将其设置为 0xCC)。

【讨论】:

  • int main(int argc, char* argv[])?
  • int main(int argc, char* argv[], char *envp[]) ?
  • @sharth:该签名不是标准的。这两个标准签名是:int main()int main( int, char** ) 任何其他签名都是非标准的。 EDIT:在审查标准后,该签名是标准允许的,实际上是返回 int 的 any 签名。它只是不可移植,因为不能保证在任何其他环境中都可用。
【解决方案2】:

又一个 MSVC 扩展/错误!

【讨论】:

  • 我不知道这是否一定是一个“错误”,因为您也可以使用 void main。但是,用 C++ 编程一段时间的人都知道 int main 是“正确”的方式,而不是“微软”的方式。
  • 哇,微软甚至在 GCC 中引入了同样的错误!
  • @Richie GCC 在 C++ 中拒绝 char mainvoid main
  • 我猜反对票的人是微软的忠实粉丝……但你不同意哪一部分?标准明确规定 main 的返回类型应为 int。时期。如果不是,那么编译器必须发出诊断。因此这是一个 MSVC BUG
  • @David: void 在 C 中不允许作为 main 的返回类型。不知道你从哪里得到这个想法。
【解决方案3】:

从主函数返回的值成为进程的退出状态,尽管 C 标准仅将特定含义赋予两个值:EXIT_SUCCESS(传统上为零)和 EXIT_FAILURE。其他可能的返回值的含义是实现定义的。但是,对于如何解释非零代码没有标准。

你可以参考一个有用的帖子:

What should main() return in C and C++?

【讨论】:

  • 这里对值的解释无关紧要。标准确定 a) 代码不正确 --> main 的返回类型 必须 是 int,并且 b) 在 main 的末尾有一个隐式的 return 0;
【解决方案4】:

第一个问题的答案是肯定的。 char 本质上是一个非常小的整数类型,因此编译器(非常)宽松。 Double 是不可接受的,因为它不是整数类型。 0xCCCCCC 是从未初始化的内存(调试目的除外)。由于 ASCII 字符只能有两个十六进制数字,因此转换根本无法设置前 24 位(而只是将后 8 位设置为 0)。多么奇怪和不受欢迎的编译器技巧。

【讨论】:

  • 错误:charint 是不同的类型,无论如何它们都不是等价的double 可隐式转换为 int(只需测试:double d = 1.5; int i = d;)。
  • 这不是垃圾。局部变量在调试版本中有意使用 0xcc 进行初始化。捕捉错误。
  • 感谢 cmets。我已经对这些更正进行了编辑。
【解决方案5】:

main 函数应该返回一个 int。不这样做意味着你在未定义的领域。不要忘记在过去的路上向标准挥手。您的 char 返回可能有效,因为 char 可以轻松转换为 int。双打肯定不行。它们不仅更长(长度加倍)而且是浮点数,这意味着您将在不稳定的地方使用 1。

简短回答:不要那样做。

【讨论】:

    【解决方案6】:

    这可能是因为 char 会隐式转换为 int,而 double 不会,因为会丢失数据。

    (请参阅此处:http://msdn.microsoft.com/en-us/library/y5b434w4%28v=VS.71%29.aspx 了解更多信息)

    但是您看不到转换问题,因为编译器捕获了使用非标准返回类型的最严重的罪过(如其他答案中所述)。

    【讨论】:

      【解决方案7】:

      关于主函数,$3.6.1/2 - "It 应具有 int 类型的返回类型, 但否则它的类型是 实现定义。”

      据我了解,标准文档中提及“应”且代码不遵守的任何内容都是编译器需要诊断的即时条件,除非标准明确规定不需要此类诊断。

      所以我猜如果 VS 允许这样的代码,它就有一个错误。

      【讨论】:

        猜你喜欢
        • 2011-07-06
        • 2013-02-17
        • 2012-03-28
        • 2011-10-01
        • 2014-10-15
        • 1970-01-01
        • 2017-05-08
        相关资源
        最近更新 更多