chq*_*lie 7 c c++ undefined-behavior language-lawyer
很明显,由于算术溢出,以下代码调用未定义的行为:
#include <limits.h>
int test(void) {
int i = INT_MAX;
i++; /* undefined behavior */
return i;
}
Run Code Online (Sandbox Code Playgroud)
但是比小于或int等的签名类型呢?(由较小的,我假定和分别地).shortsigned charSCHAR_MAX < INT_MAXSHRT_MAX < INT_MAX
以下哪个函数调用未定义的行为,为什么?
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;
}
Run Code Online (Sandbox Code Playgroud)
请提供引用或引用C标准以支持您的推理.
以下代码确实会导致溢出,从而导致未定义的行为:
signed char i = SCHAR_MAX;
i++;
Run Code Online (Sandbox Code Playgroud)
运算符后缀 ++ 不执行整数提升或通常的算术转换1。该运算符只是将操作数2的值加一。操作溢出。
一个明显的区别来自于一元算术运算符的措辞:+, -, ~,其措辞清楚地表明操作数被提升3。但对于后缀++运算符,措辞并没有说该运算符被提升为4。
显然后缀 ++ 运算符不会提升操作数。
1(引自:ISO/IEC 9899:201x 6.3.1.1 布尔值、字符和整数 2 58))
整数提升仅适用于: 作为常规算术转换的一部分、某些参数表达式、一元的操作数+、- 和 ~ 运算符,以及移位运算符的两个操作数,如其各自的子条款所指定。
2(引用自:ISO/IEC 9899:201x 6.5.2.4 后缀递增和递减运算符 2)
作为副作用,操作数对象的值会递增(即,将适当类型的值 1 添加到其中)
3 (引自:ISO/IEC 9899:201x 6.5.3.3 一元算术运算符 2)
一元 + 运算符的结果是其(提升的)操作数的值。对操作数执行整数提升,结果具有提升后的类型。
4 (引用自:ISO/IEC 9899:201x 6.5.2.4 后缀递增和递减运算符 2)
后缀 ++ 运算符的结果是操作数的值。