在下面的代码中,*(int32 *) 0 = 0;
含义是什么?
void
function (void)
{
...
for (;;)
*(int32 *) 0 = 0; /* What does this line do? */
}
Run Code Online (Sandbox Code Playgroud)
几点说明:
int32
是typedef
'但你不应该太在意它.Sco*_*uer 33
代码正在执行以下操作:
for (;;) // while(true)
*(int32 *) 0 = 0; // Treat 0 as an address, de-reference the 0 address and try and store 0 into it.
Run Code Online (Sandbox Code Playgroud)
这应该是segfault,null指针de-reference.
编辑
编译并运行以获取更多信息:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(void){
*(int32_t *) 0 = 0;
printf("done\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc -g null.c; ./a.out
Program received signal SIGSEGV, Segmentation fault.
0x00000000004004cd in main () at null.c:7
7 *(int32_t *) 0 = 0;
Run Code Online (Sandbox Code Playgroud)
Eri*_*hil 26
由于OP声明代码是由经验丰富的编译工程师编写的,因此这可能是代码的意图:
*(int32 *) 0 = 0;
被这个特定的C实现识别为导致C标准未定义且该实现已知的行为非法的代码.for (;;)
还指示该代码永远不会退出.只有当您具有C实现的内部操作的特定知识时,才可能进行这种推理.这是编译器工程师可能包含在C实现的特殊头文件中的事情,可能是为了标记某些代码(例如abort
调用后的代码)永远不会到达.它绝不应该用于普通编程.
1例如,请考虑以下代码:
if (a)
for (;;)
*(int 32 *) 0 = 0;
else
foo();
Run Code Online (Sandbox Code Playgroud)
编译器可以识别允许then子句具有任何行为.因此,编译器可以自由选择它具有的行为.为简单起见,它选择它具有相同的行为foo();
.然后代码变成:
if (a)
foo();
else
foo();
Run Code Online (Sandbox Code Playgroud)
并可进一步简化为:
foo();
Run Code Online (Sandbox Code Playgroud)
evi*_*uff 22
事实上,这段代码seg-faulting并没有解释为什么它存在=)
我认为这是来自某些MCU的运行时间...并且它的存在是因为如果程序执行到了这一点,这样的指令将启动MCU的软件复位,因此程序将重新启动(这是嵌入式开发中的常见做法)或者如果MCU配置了硬件看门狗,则由于硬件看门狗和永不结束循环而强制MCU重启.
这种结构的主要目标是调用中断,该中断可由OS或硬件处理以启动某些操作.
知道它的x86它将取决于CPU模式......在实模式下如果没有看门狗就不会立即发生任何事情,在地址0处有一个"除以0"处理程序的地址,所以如果它是一些旧的MS- DOS或嵌入式x86运行时它会将'Divide by 0'处理程序的地址更改为0,因此只要它发生并且此中断未被屏蔽,CPU将跳转到位置0:0并且可能因非法指令而重新启动..如果它受到保护或VM x86代码,那么它是一种通知操作系统或任何其他主管在运行时出现问题的方法,软件应该在外部被"杀死".
for(;;)
相当于while(1)
,
*(int32 *) 0 = 0;
将0写入一个取消引用的空指针,该指针预计会导致崩溃,但实际上并不会在某些编译器上发生崩溃:崩溃线程带*(int*)NULL = 1; 有问题?