2

从 6.3.2.1(强调我的)

如果左值指定了一个可以使用寄存器存储类声明的具有自动存储持续时间的对象(从未使用过它的地址),并且该对象未初始化(未使用初始化程序声明并且在使用之前没有对其进行分配) ),行为未定义。

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

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根据标准,我应该期待什么?

4

2 回答 2

2

在这种情况下,因为x已经获取了它的地址,所以行为不是严格未定义的。此时 的值x不确定的。这意味着该值是陷阱表示或未指定

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

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

C标准的相关段落:

第 3.19 节:

3.19.2

1 不确定值未指定值或陷阱表示

3.19.3

1 未指定值相关类型的有效值,本标准对在任何情况下选择哪个值没有要求

2注意 未指定的值不能是陷阱表示。

3.19.4

1 陷阱表示不需要表示对象类型值的对象表示

第 6.7.9p10 节:

如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。

于 2019-10-15T15:47:50.430 回答
0

除其他外,该标准使用术语“未定义行为”来描述一般情况,其中绝大多数实现将以相同的可预测的一般方式表现,但某些特定实现可能会通过表现不同来更好地为其客户服务。

考虑以下函数:

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],同时保留这些结构的其他元素无论他们以前持有什么。他们没有试图准确地描述应该允许什么样的优化,而是简单地假设实施将寻求最好地满足客户的需求。

于 2019-10-15T15:51:09.803 回答