代码崩溃编译器: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?