使用未初始化的变量而不调用未定义的行为

Using uninitialized variable without invoking undefined behavior

来自 6.3.2.1(强调我的)

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.

这意味着,如果无法使用寄存器存储class声明自动对象(已获取其地址):

int x; 

printf("just a dummy pointer print %p", &x);  //taking the address to break 6.3.2.1 UB condition

if (x == 2)
{
    print("x uninitialized value: %d", x);
} 

根据 6.3.2.1,在我使用未初始化对象的值的 if (x == 2) 中没有未定义的行为。 如果那是真的,并且这里没有 UB,那么定义的行为是什么?根据标准,我在 x 中应该期待什么?

在这种情况下,因为 x 的地址已被占用,所以行为并非严格未定义。此时x的值为不确定。这意味着该值要么是陷阱表示,要么是未指定

如果 x 恰好包含陷阱表示,则行为未定义,否则该值未指定,这意味着可以打印任何有效值。

此外,您可能遇到的大多数系统都没有任何整数类型的填充位,这意味着该实现没有陷阱表示,并且该值将始终是 未指定.

相关段落来自C standard

第 3.19 节:

3.19.2

1 indeterminate value either an unspecified value or a trap representation

3.19.3

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

2 NOTE An unspecified value cannot be a trap representation.

3.19.4

1 trap representation an object representation that need not represent a value of the object type

第 6.7.9p10 节:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

该标准使用术语 "Undefined Behavior" 来描述一般情况,在这种情况下,绝大多数实现将以相同的可预测的一般方式运行,但某些特定的实现可能会更好地为其客户服务表现不同。

考虑以下函数:

struct foo { unsigned char dat[256]; };

struct foo x,y;

void test(int a, int b)
{
  struct foo temp;
  temp.dat[a] = 1;
  temp.dat[b] = 2;
  x=temp;
  y=temp;
}

我不认为标准的作者想要要求程序员在存储它之前完全初始化 temp,但我也不认为他们想要禁止实现简单地写入 x.dat[a]y.dat[a]x.dat[b]y.dat[b],同时保留这些结构的其他元素保留它们之前保留的内容。他们并没有试图准确地描述应该允许哪些优化类型,而是简单地假设实现将寻求最好地满足客户的需求。