【问题标题】:Suppress Divide or Mod by zero Compiler Error in C用 C 中的零编译器错误抑制除法或 Mod
【发布时间】:2018-07-10 08:56:47
【问题描述】:

我正在编写一个 C 程序,我想在其中触发一个异常,以便程序在 Windows 上崩溃并调用 Windows 错误报告。

我认为,触发崩溃的一种好方法是除以零。但是,当我尝试这样做时,编译器不会编译程序并给出错误:C2124。

有没有办法强制编译器编译程序并忽略代码中的上述除以零语句?

或者我应该找到另一种方法来让我的程序崩溃吗? :)

#include <stdio.h>

int main(int argc, char **argv)
{
    return 1/0;
}

【问题讨论】:

  • 可以使用空指针访问
  • 致电abort?
  • 获取用户的输入从而绕过编译时检查?

标签: c crash divide-by-zero


【解决方案1】:

abort,在&lt;stdlib.h&gt;中定义是导致程序异常终止的首选方式。但是,针对您导致被零除的特定意图的解决方案是对编译器隐藏除数:

volatile int x = 0;
return 1/x;

关键字volatile 告诉编译器x 可能会以编译器未知的方式更改。这可以防止编译器知道它为零,因此编译器必须生成代码以在运行时执行除法,以防x 更改为非零值。

当然,被零除的行为是没有定义的,所以不能保证会导致程序终止。

还请记住,“如果你对编译器撒谎,它就会报仇雪恨。” (亨利·斯宾塞)。

【讨论】:

  • volatile 会阻止某些优化并且不是抑制警告的好方法。
  • @wonder.mice:它是否解决了 OP 在程序执行期间而不是在编译期间创建除零错误的请求,您有其他解决方案吗?没有人需要对此程序终止进行优化,并且仅在此处使用的 x 是易失性的这一事实不会影响程序其余部分的优化。
  • 我支持使用abort() 变体,只是担心volatile 技术可以被人们在实际重要的不同上下文中使用。不是要投反对票,是意外点击,但当我发现为时已晚时,抱歉。
【解决方案2】:

1/0 在编译时进行评估。编译器足够聪明,可以检测到它不起作用。

我愿意:

int a = 0;
return 1/a;

(您可能会收到警告,但它会编译)

或者触发空指针访问:

int *p = NULL;
return *p;

【讨论】:

    【解决方案3】:

    很难让 C 程序以明确定义的方式崩溃。这确实是一个矛盾的术语。

    最喜欢的方法是引发堆栈溢出、空指针取消引用和除以零。但是编译器在发现这些技巧方面做得越来越好。递归可以展开为循环,并且由于 1/0 是编译时可评估的常量表达式,并且它的行为未定义,因此允许编译器编译失败。

    更可靠的方法是使用来自&lt;stdlib.h&gt;void abort(void)。至少 C 标准保证不会返回给调用者:

    #include <stdlib.h>
    int main(int, char **)
    {
        abort();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      • 2011-06-27
      • 2018-11-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      相关资源
      最近更新 更多