Is the compiler allowed to store a larger value in an 8-bit uninitialized variable?
(允许编译器在8位未初始化的变量中存储较大的值吗?)
I have an example code to illustrate the issue.
(我有一个示例代码来说明这个问题。)
#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
");
return 597;
}
csum += result[i];
}
return csum;
}
char a[] = "48454c4c4f";
char b[20];
int main() {
printf("%d
", unhex(a,b,5));
printf("%s
", b);
}
When running the above code under -Og
optimization, it reads:
(在-Og
优化下运行上述代码时,其内容为:)
597
HELLO
When it should clearly output something that is 8-bit , ie in [0, 256).
(当它应该清楚地输出8位的内容时 ,即[0,256)。)
My GCC version is gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0
and I run gcc -o stuff -Og -ggdb -Wall -Wextra -Wuninitialized -Wmaybe-uninitialized stuff.c
to compile it.
(我的GCC版本是gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0
,我运行gcc -o stuff -Og -ggdb -Wall -Wextra -Wuninitialized -Wmaybe-uninitialized stuff.c
进行编译。)
And it does not warn about the possibly unininitialized variable. (并且它不会警告可能未初始化的变量。)
I know that this is UB, but is it really allowed even to such extent? (我知道这是UB,但是在这样的范围内,真的可以吗?)
I understand that what goes on here is that GCC optimizes csum
out entirely, and treats return csum
just as if it was never there in the first place.
(我知道这里发生的事情是,GCC完全优化了csum
,并将return csum
当作一开始就没有出现。)
So there are two questions, actually:
(因此,实际上有两个问题:)
EDIT : the funny thing is that if +=
is replaced by =
, the compiler complains, just like it should, near the return line:
(编辑 :有趣的是,如果+=
被替换=
,编译器会抱怨,就像它应该接近返回行:)
stuff.c: In function ‘unhex’:
stuff.c:14:10: warning: ‘csum’ may be used uninitialized in this function [-Wmaybe-uninitialized]
return csum;
^~~~
ask by Arusekk translate from so