代码崩溃编译器:main() 返回结构而不是 int

Posted

技术标签:

【中文标题】代码崩溃编译器:main() 返回结构而不是 int【英文标题】:Code crashing compiler: main() returning a struct instead of an int 【发布时间】:2011-02-28 22:39:07 【问题描述】:

我正在试验一段 C 代码。谁能告诉我为什么带有 SP1 的 VC 9.0 会崩溃?哦,代码是为了作为讨论中使用的示例,为什么像

 void main (void)

是邪恶的。

struct foo  int i; double d;  main (double argc, struct foo argv)


    struct foo a;
    a.d=0;
    a.i=0;
    return a.i;

如果我放了

return a;

编译器不会崩溃。

【问题讨论】:

编译器根本不应该崩溃,如果它在试图理解你的代码时崩溃,那就是编译器的一个错误。 +1 代表讨厌的例子。花了我一点时间才弄清楚你在做什么:)另外,VS2010 C++ 编译器现在强制执行 main() 的签名(iow,上面的代码不再编译)。 尝试用分号关闭结构。看看这是否会改变编译器的行为。这可能确实是一个编译器错误。 顺便说一句,我对 VS2010 C++ 编译器印象深刻,因为它更好地执行了标准——包括头文件末尾的那些讨厌的回车! @AndrejaKo:您可以在connect.microsoft.com 上提交缺陷报告,我可以确认在 Visual C++ 2010 中也发生了内部编译器错误,所以最好的办法是报告该版本,因为它是然后更有可能修复(如果您不想报告它,我可以报告它......无论哪种方式。如果您确实报告了缺陷,请务必在此处发布链接,以便人们可以根据需要对其进行投票) . 【参考方案1】:

代码给出了未定义的行为。这并不要求编译器崩溃,它只是说你基本上违反了规则,所以无论发生什么,编译器都没有做错任何事情。

编辑:也就是说,作为一个实施质量问题,编译器基本上没有任何借口崩溃是绝对正确的——合理地说,它应该总是正常退出,无论你提供什么数据。

【讨论】:

错误的代码不应该让编译器崩溃。如果程序本身由于未定义的行为而崩溃是另一回事。 也许如果编译器在这种令人发指的构造上更频繁地崩溃,我们就不会在野外看到这种可怕的代码。 +100 让任何试图编译上述内容的人崩溃。 我记得在某处读到过一个“黑客的”C 编译器,它在成功时不会输出任何内容,但在 any 错误时只会输出“No”。 @dreamlax 错误应该只输出退出代码 1,愚蠢的。【参考方案2】:

好的,你想提出一个深奥的问题,那么请构建一个完整的问题。

您是如何进行测试的? 你说的崩溃是什么意思? 你的输出是什么? 是直接编译,还是编译链接,还是编译链接调试? 你的编译器是如何配置的? 你要去哪里做这个实验?

诸如“something like”、“evil”之类的短语信息不够丰富,没有用处

跟进:

我本能地猜测这次崩溃是编译器的结果 允许编译器使用的优化开关 您不符合某些假设。

我的假设:

1- void main(void)(不带 ;)是您正在发表的评论的一部分,但不是 您提交的测试的一部分。

2- 您的程序不正确,但这是故意的,以便进行调查 编译器/链接器/执行环境的行为。 如果确实如此,则需要降低测试用例的复杂度。

请将测试用例简化到导致崩溃的最低限度。 我不能为你做,我没有正确的软件版本 安装,无论如何,这是你的实验。

这会崩溃吗?

   struct foo  int i; double d; ;
   struct foo main( void)
       
       int a=0;
       return a;
       

甚至这个最小的例子?

   void * main(void)
   
   return 0;
   

是不是这个(我怀疑):

   int main( double argc, char ** argv)
   
   return 0;
   

你明白了。将崩溃减少到本质。 想出一个没有错误的程序,除了 一件事会让它崩溃。

然后报告回来。

【讨论】:

Here' 如何重现问题:启动 Visual Studio 2008 SP1 并创建一个新的空 C++ 项目。添加一个新的源文件并手动添加 .c 扩展名。这样它将被编译为 C。按 F7。如果您没有更改任何设置,它将构建一个调试版本。结果:Microsoft 优化编译器已停止工作。事件名称:APPRCASH。哦,我又读了一遍这个问题。邪恶之类的东西已经足够丰富了。它们的存在点是避免像“C 标准说 int main (void) blah blah blah”这样的 cmets,因为我已经知道 :) 并且还描述了代码的使用 1 和 2 是正确的。我想我有时不能很好地表达自己。您现在对我们的回答实际上很有用,所以 +1 并感谢您的想法。【参考方案3】:

在结构的末尾和 main 之间放置一个分号,如下所示:

struct foo int i;双 d; ; main (double argc, struct foo argv)

如果你要返回一些东西,你也可以为 main 定义一个返回类型:

struct foo int i;双 d; ; int main (double argc, struct foo argv)

【讨论】:

以上是关于代码崩溃编译器:main() 返回结构而不是 int的主要内容,如果未能解决你的问题,请参考以下文章

libtorrent 和 tcp::acceptor 在 Windows 上因访问冲突而崩溃

为啥 main 的默认返回值为 0 而不是 EXIT_SUCCESS?

可以/为啥在返回类型中使用 char * 而不是 const char * 会导致崩溃?

C# 结构到字节数组封送产生 19 个元素而不是 20 个

使 malloc() 返回 NULL 而不是使程序崩溃?

Exception in thread "main" java.lang.NoClassDefFoundError