是否允许优化的out变量保存超出其范围的值?

是否允许编译器在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一样,根本就没有它。

实际上有两个问题:

  • 是不是编译器无法将这样的动作通知程序员(显然在整个代码中没有明确地分配csum?),或者仅仅是GCC的错误/缺陷?
  • C标准是否允许有关未定义变量的UB? (实际上是在存储超出类型范围的值)

EDIT :有趣的是,如果将+=替换为=,则编译器会像在返回行附近一样抱怨:

stuff.c: In function ‘unhex’:
stuff.c:14:10: warning: ‘csum’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   return csum;
          ^~~~
J943768044 回答:是否允许优化的out变量保存超出其范围的值?

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/2999450.html

大家都在问