是否允许编译器在8位未初始化的变量中存储较大的值?
我有一个示例代码来说明这个问题。
#include <stdio.h>
#include <inttypes.h>
int unhex(char *data, char *result, unsigned length)
{
uint8_t csum; /* in a working code it should be =0 */
for (unsigned i = 0; i < length; i++) {
if (!sscanf(data + 2*i, "%2hhx", result + i)) {
printf("This branch is never taken\n");
return 597;
}
csum += result[i];
}
return csum;
}
char a[] = "48454c4c4f";
char b[20];
int main() {
printf("%d\n", unhex(a,b,5));
printf("%s\n", b);
}
在-Og
优化下运行上述代码时,它显示为:
597
HELLO
何时应该清楚地输出 8位,即[0,256)。
我的GCC版本为gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0
,我运行gcc -o stuff -Og -ggdb -Wall -Wextra -Wuninitialized -Wmaybe-uninitialized stuff.c
进行编译。并且它不会警告可能未初始化的变量。我知道这是UB,但是在这样的范围内,真的可以吗?
我知道这里发生的是GCC完全优化了csum
,并像对待return csum
一样,根本就没有它。
实际上有两个问题:
EDIT :有趣的是,如果将+=
替换为=
,则编译器会像在返回行附近一样抱怨:
stuff.c: In function ‘unhex’:
stuff.c:14:10: warning: ‘csum’ may be used uninitialized in this function [-Wmaybe-uninitialized]
return csum;
^~~~