【发布时间】:2019-09-14 19:10:07
【问题描述】:
虽然所有这些断言在我的系统上都成立,但我显然是在调用几个未定义和/或特定于实现的行为。其中一些 显然不是实际溢出。
参考this comment:这就是我问这个问题的原因。
num = num + 1不会导致溢出。num自动提升为int,然后在int中进行加法,得到128 没有溢出。然后赋值执行到char的转换。这不是溢出,但根据 C 2018 6.3.1.3,会产生实现定义的结果或信号。这与溢出不同,因为 C 标准根本没有指定溢出时的行为,但是在这段代码中,它指定实现必须定义行为。 - 埃里克·波斯特皮希尔
我将我认为的实际行为发表评论。
因为我依赖于误解,所以我不想假设任何事情。
#include <limits.h>
#include <assert.h>
#include <stdint.h>
#include <stddef.h>
int main(void)
{
signed char sc = CHAR_MAX;
unsigned char uc = UCHAR_MAX;
signed short ss = SHRT_MAX;
unsigned short us = USHRT_MAX;
signed int si = INT_MAX;
unsigned int ui = UINT_MAX;
signed long sl = LONG_MAX;
unsigned long ul = ULONG_MAX;
size_t zu = SIZE_MAX;
++sc;
++uc;
++ss;
++us;
++si;
++ui;
++sl;
++ul;
++zu;
assert(sc == CHAR_MIN); //integer promotion, implementation specific ?
assert(uc == 0); //integer promotion, implementation specific ?
assert(ss == SHRT_MIN); //integer promotion, implementation specific ?
assert(us == 0); //integer promotion, implementation specific ?
assert(si == INT_MIN); //overflow & undefined
assert(ui == 0); //wrap around: Guaranteed
assert(sl == LONG_MIN); //overflow & undefined ?
assert(ul == 0); //wrap around: Guaranteed ?
assert(zu == 0); //wrap around : Guaranteed ?
return (0);
}
【问题讨论】:
-
我觉得
num = num + 1和++num可能在这方面有细微的差别 -
而
size_t只是另一种类型的typedef
标签: c assert integer-overflow