为了账号安全,请及时绑定邮箱和手机立即绑定

如果未初始化a^a或a-是未定义的行为?

如果未初始化a^a或a-是未定义的行为?

C
繁星淼淼 2019-07-20 12:56:43
如果未初始化a^a或a-是未定义的行为?考虑一下这个项目:#include <stdio.h>int main(void){     unsigned int a;     printf("%u %u\n", a^a, a-a);     return 0;}这是不明确的行为吗?从表面上看,a是未初始化的变量。这就指向了不明确的行为。但a^a和a-a等于0的所有值a至少我认为是这样的。是否有可能以某种方式证明这种行为是有明确定义的?
查看完整描述

3 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

在C11中:

  • 根据6.3.2.1/2显式未定义

    a

    其地址从未被取走(引用如下)
  • 它可能是陷阱表示(当访问UB时会导致UB)。6.2.6.1/5:

某些对象表示不需要表示对象类型的值。

无符号INT可以有陷阱表示(例如,如果它有15个精确位和1个奇偶位,则访问a可能导致奇偶错误)。

6.2.4/6表示初始值为不确定而3.19.2项下的定义是未指定的值或陷阱表示.

此外:正如Pascal Cuoq所指出的,在C11 6.3.2.1/2号文件中:

如果lvalue指定可以用寄存器存储类声明的具有自动存储持续时间的对象(从未使用其地址),且该对象未初始化(未使用初始化器声明,且未在使用前对其执行赋值),则行为未定义。

这对于字符类型没有异常,因此这个子句似乎取代了前面的讨论;x立即未定义,即使不存在陷阱表示。本条款添加到C11中支持真正具有寄存器陷阱状态的Itanium CPU。


没有陷阱表示的系统:但如果我们把&x;所以6.3.2.1/2的反对不再适用,而我们所处的系统是已知的没有陷阱表示的系统?则值为未指定值..对…的定义未指定值在3.19.3中有点模糊,但是451博士,其结论是:

  • 在所述条件下未初始化的值似乎会更改其值。
  • 因此,对不确定值执行的任何操作都将具有不确定值。
  • 当对不确定值使用时,库函数将显示出未定义的行为。
  • 这些答案适用于所有没有陷阱表示的类型。

根据这项决议,int a; &a; int b = a - a;结果b仍有不定值的。

请注意,如果不确定值未传递给库函数,则仍处于未指定行为(不是未定义行为)的范围内。结果可能很奇怪。if ( j != j ) foo();可以打电话给Foo,但恶魔必须安顿在鼻腔里。


查看完整回答
反对 回复 2019-07-20
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

是的,这是未定义的行为。

首先,任何未初始化的变量都可能有“断开”(也称为“陷阱”)表示。即使一次访问该表示的尝试也会触发未定义的行为。此外,即使是非捕获类型的对象(如unsigned char)仍然可以获得特殊的依赖于平台的状态(比如Itanium上的NAT而不是A),这些状态可能会显示出它们的“不确定性价值”。

其次,未初始化的变量不一定具有稳定价值。对同一个未初始化变量的两个顺序访问可以完全读取。异类值,这就是为什么,即使两者都访问a - a是“成功”(不是陷阱),仍然不能保证a - a将评估为零。


查看完整回答
反对 回复 2019-07-20
  • 3 回答
  • 0 关注
  • 410 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信