是否会为小于int的带符号类型调用未定义的行为

是否会为小于int的带符号类型调用未定义的行为

本文介绍了如果发生溢出,i ++是否会为小于int的带符号类型调用未定义的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很明显,以下代码由于算术溢出而调用了未定义的行为:

It seems clear that the following code invokes undefined behavior because of arithmetic overflow:

#include <limits.h>

int test(void) {
    int i = INT_MAX;
    i++;  /* undefined behavior */
    return i;
}

但是小于 int 的签名类型(例如 short signed char )如何呢?(更小些,我分别假设 SCHAR_MAX< INT_MAX SHRT_MAX< INT_MAX ).

But what about signed types smaller than int such as short or signed char? (by smaller, I assume SCHAR_MAX < INT_MAX and SHRT_MAX < INT_MAX respectively).

下面的哪个函数调用未定义的行为,为什么?

Which of the functions below invoke undefined behavior and why?

signed char test2(void) {
    signed char i = SCHAR_MAX;
    i = i + 1;   /* implementation defined */
    return i;
}

signed char test3(void) {
    signed char i = SCHAR_MAX;
    i += 1;   /* undefined behavior or implementation defined? */
    return i;
}

signed char test4(void) {
    signed char i = SCHAR_MAX;
    i++;      /* undefined behavior or implementation defined? */
    return i;
}

signed char test5(void) {
    signed char i = SCHAR_MAX;
    ++i;      /* undefined behavior or implementation defined? */
    return i;
}

请提供C标准的引用或引用以支持您的推理.

Please provide references from or quote the C Standard to support your reasoning.

推荐答案

对于 + = 和类似的运算符,直接对目标类型的值进行操作以及在许多实现上都是合乎逻辑的实际上是他们所做的.但是,该标准要求操作员的行为要像目的地的值经过任何适用的标准和平衡促销一样,然后处理指定的操作,然后转换回目的地类型.

It would be logical for the += and similar operators to operate directly on values of the destination type, and on many implementations that is in fact what they do. The Standard, however, requires that the operator behave as though the value of the destination undergoes any applicable standard and balancing promotions, then processes the specified operation, and then gets converted back to the destination type.

因此,如果 s u 是带符号和无符号的16位变量,而 int 是32位,则 s* = s; 将为 s 的所有值定义[如果结果超过32767,则它必须产生实现定义的值或引发实现定义的信号;除了减少二进制补码之外,大多数实现都必须竭尽所能].另一方面, u * = u; 仅保证将mod 65536封装为 u 的值(最大为46340);对于较大的值,它将调用未定义的行为.

Consequently, if s and u are signed and unsigned 16-bit variables, and int is 32 bits, then s*=s; will be defined for all values of s [if the result exceeds 32767, it must either yield an implementation-defined value or raise an implementation-defined signal; most implementations would have to go out of their way to do anything other than two's-complement reduction]. On the other hand, u*=u; will only be guaranteed to wrap mod 65536 for values of u up to 46340; for larger values, it will invoke Undefined Behavior.

这篇关于如果发生溢出,i ++是否会为小于int的带符号类型调用未定义的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 11:07