我在某处看到了这段代码,这不是整数溢出和未定义的行为吗?
假设0 < str[i] < 127
char *msl_decrypt(char *str) {
char *decrypted;
unsigned int i;
int key = 0xFACA;
for (i = 0; i < strlen(str); ++i) {
str[i] = str[i] + key; // referring to this line, is it UB?
}
...
答案 0 :(得分:5)
太糟糕了,你没有指定目标参数。所以对于以下我的假设:
CHAR_BIT == 8
sizeof(int) >= 2
str
指向有效且已初始化的内存,该内存已正确nul
- 终止且不大于INT_MAX
(或者使用size_t
进行索引 - 感谢@chux)。< / LI>
这些是大多数现代实施的典型。
对于sizeof(int) == 2
,初始化程序是实现定义的行为,因为您使用unsigned int
常量作为初始化程序。对于更宽的int
,这是可以的。如果(int)(0xFACA) + CHAR_MAX > INT_MAX
(算术上,也只与2字节int
相关),情况也会变得更加复杂。
其余的以更复杂的方式依赖于实现定义的行为:
1)添加str[i] + key
:此处str[i]
首先转换为int
,添加的结果为int
,结果为int
。< / p>
2)作业str[i] = ...
:此处添加的int
结果将转换为char
。为此,我们有两个变体,具体取决于char
(实现定义)的签名:
unsigned char
。signed char
。所以:没有 未定义的行为,但是(以及评论)显示了在C中使用有符号整数时必须记住的程度。
<强>可是:强>
涉及太多实现定义的行为并且需要许多先决条件(尽管这很常见)。最好在整个代码中使用unsigned char
和unsigned int
。这将使代码标准兼容并且表现良好。即使是CHAR_BIT
以外的值。如果您依赖8位值,请使用uint8_t
中的stdint.h
。