来自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
有什么期望?
答案 0 :(得分:2)
在这种情况下,由于x
已获取地址,因此行为并非严格未定义。此时x
的值为不确定的。这意味着该值为陷阱表示或未指定。
如果x
恰好包含陷阱表示,则该行为未定义,否则该值未指定,这意味着可以打印任何有效值。
此外,您可能会遇到的大多数系统都没有整数类型的填充位,这意味着该实现上没有陷阱表示,并且值始终为未指定。< / p>
C standard的相关段落:
第3.19节:
3.19.2
1 不确定值是未指定的值还是陷阱的表示形式
3.19.3
1 未指定值本国际标准未规定任何要求的相关类型的有效值 在任何情况下选择哪个值
2 注意未指定的值不能是陷阱表示。
3.19.4
1 陷阱表示不需要表示对象类型值的对象表示
第6.7.9p10节:
如果具有自动存储持续时间的对象不是 显式初始化,其值不确定。
答案 1 :(得分: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]
,而这些结构的其他元素则保留它们以前保存的内容。他们并没有试图确切地描述应该允许哪种类型的优化,而是仅仅假设实现将寻求最佳地满足其客户的需求。