Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
568 views
in Technique[技术] by (71.8m points)

c - 是否允许优化的out变量保存超出其范围的值?(Is an optimized out variable allowed to hold a value out of its range?)

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:

(因此,实际上有两个问题:)

  • Is it that the compiler cannot inform the programmer of such an action (clearly no explicit assignment to csum throughout the code), or is it just a bug/caveat of GCC?

    (难道是编译器无法将这样的动作通知程序员(显然在整个代码中都没有对csum的明确分配),还是仅仅是GCC的错误/缺陷?)

  • Does the C standard permit such UB concerning undefined variables?

    (C标准是否允许涉及未定义变量的此类UB?)

    (here de facto storing a value out of type range)

    ((实际上是在存储超出类型范围的值))

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...