GCC 4.8.0编译/为32位.
我发现案例2和案例6的行为令人困惑:
int16_t s16 = 0;
double dbl = 0.0;
s16 = (int16_t)((double)32767.0); // 1: s16 = 32767
s16 = (int16_t)((double)32768.0); // 2: s16 = 32767
s16 = (int16_t)((double)-32768.0); // 3: s16 = -32768
s16 = (int16_t)((double)-32769.0); // 4: s16 = -32768
dbl = 32767.0;
s16 = (int16_t)dbl; // 5: s16 = 32767
dbl = 32768.0;
s16 = (int16_t)dbl; // 6: s16 = -32768
dbl = -32768.0;
s16 = (int16_t)dbl; // 7: s16 = -32768
dbl = -32769.0;
s16 = (int16_t)dbl; // 8: s16 = -32768
Run Code Online (Sandbox Code Playgroud)
我意识到它的实现是定义的,但一致性仍然很好.谁能解释一下发生了什么?
根据 6.3.1.4 (1),该行为不是实现定义的,而是未定义的:
\n\n\n如果整数部分的值不能用整数类型表示,则行为未定义。61)
\n61)当实数浮点类型的值转换为无符号类型时,不需要执行整数类型的值转换为无符号类型时执行的余数运算。因此,可移植实浮点值的范围是
\n(\xe2\x88\x921, Utype_MAX+1)。
该段落在 C99 中是相同的,只是脚注的编号不同 (50)。
\n对于未定义的行为,编译时求值的表达式的行为与运行时求值的行为不同并不罕见,例如
\n1 << width_of_type\nRun Code Online (Sandbox Code Playgroud)\n如果移动距离作为常量表达式给出,则通常评估为 0;如果是运行时值,则通常评估为 1。
\n据我所知,导致同一代码出现不同行为的原因是,由于未定义的行为是编译器生成任何内容的许可证,因此它也可能会做最简单和/或最快的事情,以及最简单的事情编译期间/最快的事情可能与运行时最简单/最快的事情不同。
\n| 归档时间: |
|
| 查看次数: |
153 次 |
| 最近记录: |