为什么goto这个宏定义会导致程序崩溃?
Why this macro define of goto will crash the program?
我正在阅读一篇post,其中一个答案中有以下代码
#define goto { int x = *(int *)0; } goto
作者说每次有人尝试使用 goto 语句时,他的程序都会崩溃,我的问题是为什么?按照我的理解,int x = *(int *)0;
是把内存地址的前4个字节的whatever内容赋值给x
,但是为什么这样肯定会导致程序崩溃呢?
只是因为您正在取消引用 NULL
指针。但是然后程序会崩溃是没有定义的。它可能会崩溃,可能不会崩溃或者做一些奇怪的事情。这只是一种未定义的行为,最好避免。
值得注意的是,goto
并不是那么无用。每个关键字都有自己的位置,语言作者和标准委员会成员有理由继续维护它(考虑到语言正在发生一些巨大的变化)。如果使用得当,goto 在 C 和 C++ 中占有一席之地。
Just to give an idea how this is an UB, using VC11, I compiled the
above snippet in debug and release mode. In debug mode it crashed but
in release mode, compiler simply optimized out the statement and there
was no crash.
在C或C++中,内存地址0代表一个NULL指针。取消引用这样的指针始终是未定义的行为,并且在大多数实现中它会引发分段错误,有效地 "crashing" 程序。
代码在两个方面给出了未定义的行为。
首先,重新定义语言关键字本身会产生未定义的行为。
其次,正如其他人所说,值为“0”的指针是 NULL 指针,取消引用它会产生未定义的行为。
构造的实际结果因此是未定义的行为。未定义行为的常见症状是程序崩溃。但是,实际上并不能保证崩溃。甚至不需要。
作为编写宏的"why?",该代码的作者显然是"goto is evil"阵营的订阅者,并认为可以任意对his/her造成不知情的偏见其他。实际上,goto
有其用途,即使替代方案通常更可取。甚至 Dijkstra(人们经常引用原论文来证明不使用 goto
的作者)也只是描述了无节制使用的问题,并没有声称应该简单地避免它。 Donald Knuth 后来在 70 年代中期写了一篇关于该主题的论文,其中包括使用 goto
有益的示例。
我正在阅读一篇post,其中一个答案中有以下代码
#define goto { int x = *(int *)0; } goto
作者说每次有人尝试使用 goto 语句时,他的程序都会崩溃,我的问题是为什么?按照我的理解,int x = *(int *)0;
是把内存地址的前4个字节的whatever内容赋值给x
,但是为什么这样肯定会导致程序崩溃呢?
只是因为您正在取消引用 NULL
指针。但是然后程序会崩溃是没有定义的。它可能会崩溃,可能不会崩溃或者做一些奇怪的事情。这只是一种未定义的行为,最好避免。
值得注意的是,goto
并不是那么无用。每个关键字都有自己的位置,语言作者和标准委员会成员有理由继续维护它(考虑到语言正在发生一些巨大的变化)。如果使用得当,goto 在 C 和 C++ 中占有一席之地。
Just to give an idea how this is an UB, using VC11, I compiled the above snippet in debug and release mode. In debug mode it crashed but in release mode, compiler simply optimized out the statement and there was no crash.
在C或C++中,内存地址0代表一个NULL指针。取消引用这样的指针始终是未定义的行为,并且在大多数实现中它会引发分段错误,有效地 "crashing" 程序。
代码在两个方面给出了未定义的行为。
首先,重新定义语言关键字本身会产生未定义的行为。
其次,正如其他人所说,值为“0”的指针是 NULL 指针,取消引用它会产生未定义的行为。
构造的实际结果因此是未定义的行为。未定义行为的常见症状是程序崩溃。但是,实际上并不能保证崩溃。甚至不需要。
作为编写宏的"why?",该代码的作者显然是"goto is evil"阵营的订阅者,并认为可以任意对his/her造成不知情的偏见其他。实际上,goto
有其用途,即使替代方案通常更可取。甚至 Dijkstra(人们经常引用原论文来证明不使用 goto
的作者)也只是描述了无节制使用的问题,并没有声称应该简单地避免它。 Donald Knuth 后来在 70 年代中期写了一篇关于该主题的论文,其中包括使用 goto
有益的示例。