(为什么)使用C中的未初始化的变量未定义的行为? [英] (Why) is using an uninitialized variable undefined behavior in C?

查看:175
本文介绍了(为什么)使用C中的未初始化的变量未定义的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有:

unsigned int x;
x -= x;

很显然, X 的是这个前pression后为零,但我到处看看,他们说的行为的这个code是不确定的,而不仅仅是值 X (直到减法之前)。

it's clear that x should be zero after this expression, but everywhere I look, they say the behavior of this code is undefined, not merely the value of x (until before the subtraction).

两个问题:


  • 是的行为的这个code确实未定义的?结果
    (例如可能会在code崩溃[或更糟]一个兼容的系统上?)

  • Is the behavior of this code indeed undefined?
    (E.g. Might the code crash [or worse] on a compliant system?)

如果是这样, 为什么并Ç说,的行为的是不确定的,当它是非常清楚, X 这里应该是零?

If so, why does C say that the behavior is undefined, when it is perfectly clear that x should be zero here?

即。什么是的优势的通过这里没有定义的行为给予?

i.e. What is the advantage given by not defining the behavior here?

显然,编译器可以简单地使用的任何的垃圾价值它认为是得心应手的变量中,它会按预期工作...有什么不妥的做法?

Clearly, the compiler could simply use whatever garbage value it deemed "handy" inside the variable, and it would work as intended... what's wrong with that approach?

推荐答案

是的,这行为是不确定的,但出于不同的原因比大多数人都知道的。

Yes this behavior is undefined but for different reasons than most people are aware of.

首先,使用未初始化值本身不是不确定的行为,但价值简直是不确定的。访问这便是UB如果值正好是该类型陷阱重新presentation。无符号类型很少有重陷presentations,所以你会在那边比较安全的。

First, using an unitialized value is by itself not undefined behavior, but the value is simply indeterminate. Accessing this then is UB if the value happens to be a trap representation for the type. Unsigned types have rarely trap representations, so you would be relatively safe on that side.

是什么让未定义行为是您的变量的一个附加属性,即它可能已被宣布与注册这是它的地址从来没有采取。这样的变量被特殊处理,因为有有有几分额外的状态是未初始化,并且不符合在类型域的值真正的CPU寄存器架构。

What makes the behavior undefined is an additional property of your variable, namely that it "could have been declared with register" that is its address is never taken. Such variables are treated specially because there are architectures that have real CPU registers that have a sort of extra state that is "uninitialized" and that doesn't correspond to a value in the type domain.

编辑:的标准的相关语句是6.3.2.1p2:

The relevant phrase of the standard is 6.3.2.1p2:

如果左值指定自动存储持续时间的对象,
  可能已宣布与寄存器存储类(从未有过
  其地址获取),并且该对象是未初始化(未声明
  有一个初始化并没有分配给它之前已经被执行
  使用),则该行为是不确定的。

If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

和以使其更清晰,下面code的的情况下都合法的:

And to make it clearer, the following code is legal under all circumstances:

unsigned char a, b;
memcpy(&a, &b, 1);
a -= a;


  • 这里的地址 A B 已被占用,所以他们的价值仅仅是
    不确定的。

  • 由于 unsigned char型从来没有陷阱再presentations
    这不确定的值就是不确定的,的任何值unsigned char型
    发生。

  • 在结束 A 必须的保存值 0

    • Here the addresses of a and b are taken, so their value is just indeterminate.
    • Since unsigned char never has trap representations that indeterminate value is just unspecified, any value of unsigned char could happen.
    • At the end a must hold the value 0.
    • EDIT2: A B 有未指定的值:

      3.19.3 未指定值

          相关类型,其中本国际标准中并没有规定要求的有效价值上的价值
        选择在任何情况

      3.19.3 unspecified value
      valid value of the relevant type where this International Standard imposes no requirements on which value is chosen in any instance

      这篇关于(为什么)使用C中的未初始化的变量未定义的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆