在这个有条件的陈述中是否有可能被零除?

时间:2016-07-17 15:49:22

标签: c ternary-operator conditional-operator divide-by-zero

这是我的想法,因为我似乎无法发现此代码的任何问题。

无论如何,这是谜语:

假设某人将随机值注入a, b

int foo(int a, int b)
{
    return b ? (a / b): 0;
}
始终

b != 0

是否可能发生整数零除法异常?

我开始认为这是一个恶作剧,但是......

注:

这个问题发表在一个会议上,作者有可能特定于编译器/架构,这是有问题的。

2 个答案:

答案 0 :(得分:4)

不,这里不可能除以零。

引用t,章节§6.5.15,条件运算符,(强调我的

  

评估第一个操作数;它的评价和评价之间有一个序列点   评估第二或第三操作数(以评估者为准)。第二个操作数   仅当第一个比较不等于0时评估;第三个操作数仅在以下情况下进行评估   第一个比较等于0; [...]

因此,如果this为0,则不会评估表达式C11

那说,就像注:

  • 除法是整数除法。
  • 如果你有一个包装器,确保b,那么你可以减少整个函数调用,只需写(a/b)

另外,我不知道(可能)改变上述行为的任何架构。

答案 1 :(得分:3)

在您的示例中,0不可能进行除法,但您应检查另一个特殊情况:将INT_MIN除以-1可能导致除法溢出,并且通常会在英特尔硬件上造成致命异常,这是一种令人惊讶的行为,但与C标准一致,指定整数溢出可能导致特定于实现的行为。

如果您需要防止此类不受欢迎的行为,您必须特别注意这些操作数并专门处理它们:

#include <limits.h>

int foo(int a, int b) {
    if (b == 0) return 0;
    if (a == INT_MIN && b == -1) return INT_MAX;
    return a / b;
}

由于ab的值可以由外部源制作,因此您肯定需要担心除法溢出。这是一个有趣的游戏,通过向他们提供这些值来尝试碰撞不安全的计算器。