【问题标题】:Code crashing compiler: main() returning a struct instead of an int代码崩溃编译器:main() 返回结构而不是 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 中也发生了内部编译器错误,所以最好的办法是报告该版本,因为它是然后更有可能修复(如果您不想报告它,我可以报告它......无论哪种方式。如果您确实报告了缺陷,请务必在此处发布链接,以便人们可以根据需要对其进行投票) .

标签: c visual-studio-2008 visual-c++ crash compiler-errors


【解决方案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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多