用 C 中的零编译器错误抑制除法或 Mod
Suppress Divide or Mod by zero Compiler Error in C
我正在编写一个 C 程序,我想在其中触发异常,使程序在 Windows 崩溃并调用 Windows 错误报告。
我认为,引发崩溃的一种好方法是除以零。但是,当我尝试这样做时,编译器不会编译程序并给出错误:C2124.
有什么方法可以强制编译器编译程序并忽略代码中的上述除零语句吗?
或者我应该找到另一种方法让我的程序崩溃吗? :)
#include <stdio.h>
int main(int argc, char **argv)
{
return 1/0;
}
1/0
在编译时计算。编译器足够聪明,可以检测到它无法正常工作。
我会做:
int a = 0;
return 1/a;
(您可能会收到警告,但会编译)
或者触发空指针访问:
int *p = NULL;
return *p;
很难让 C 程序以明确定义的方式崩溃。真是自相矛盾。
最喜欢的方法是引发堆栈溢出、空指针取消引用和除以零。但是编译器越来越善于发现这些技巧。递归可以展开为循环,并且由于 1/0
是一个编译时可计算的常量表达式,并且它的行为是未定义的,因此允许编译器编译失败。
更可靠的方法是使用 <stdlib.h>
中的 void abort(void)
。至少 C 标准保证不会 return 给调用者:
#include <stdlib.h>
int main(int, char **)
{
abort();
}
abort
,在<stdlib.h>
中定义是导致程序异常终止的首选方式。但是,针对您导致被零除的特定意图的解决方案是对编译器隐藏除数:
volatile int x = 0;
return 1/x;
关键字 volatile
告诉编译器 x
可能会以编译器未知的方式更改。这可以防止编译器知道它为零,因此编译器必须生成代码以在 运行 时间执行除法,以防 x
更改为非零的值。
当然,除零行为没有定义,所以不保证会导致程序终止。
还要记住“如果你对编译器撒谎,它会报复的。” (亨利·斯宾塞)。
我正在编写一个 C 程序,我想在其中触发异常,使程序在 Windows 崩溃并调用 Windows 错误报告。
我认为,引发崩溃的一种好方法是除以零。但是,当我尝试这样做时,编译器不会编译程序并给出错误:C2124.
有什么方法可以强制编译器编译程序并忽略代码中的上述除零语句吗?
或者我应该找到另一种方法让我的程序崩溃吗? :)
#include <stdio.h>
int main(int argc, char **argv)
{
return 1/0;
}
1/0
在编译时计算。编译器足够聪明,可以检测到它无法正常工作。
我会做:
int a = 0;
return 1/a;
(您可能会收到警告,但会编译)
或者触发空指针访问:
int *p = NULL;
return *p;
很难让 C 程序以明确定义的方式崩溃。真是自相矛盾。
最喜欢的方法是引发堆栈溢出、空指针取消引用和除以零。但是编译器越来越善于发现这些技巧。递归可以展开为循环,并且由于 1/0
是一个编译时可计算的常量表达式,并且它的行为是未定义的,因此允许编译器编译失败。
更可靠的方法是使用 <stdlib.h>
中的 void abort(void)
。至少 C 标准保证不会 return 给调用者:
#include <stdlib.h>
int main(int, char **)
{
abort();
}
abort
,在<stdlib.h>
中定义是导致程序异常终止的首选方式。但是,针对您导致被零除的特定意图的解决方案是对编译器隐藏除数:
volatile int x = 0;
return 1/x;
关键字 volatile
告诉编译器 x
可能会以编译器未知的方式更改。这可以防止编译器知道它为零,因此编译器必须生成代码以在 运行 时间执行除法,以防 x
更改为非零的值。
当然,除零行为没有定义,所以不保证会导致程序终止。
还要记住“如果你对编译器撒谎,它会报复的。” (亨利·斯宾塞)。