gpt4 book ai didi

c - 访问未初始化的变量时避免未定义的行为

转载 作者:太空宇宙 更新时间:2023-11-04 07:02:18 25 4
gpt4 key购买 nike

假设我定义了一个 unsigned char foo;,标准保证它没有陷阱表示。根据this answer ,在其地址被占用之前访问它仍然是未定义的行为。这是 N1570 的引用资料,“6.3.2.1 左值、数组和函数指示符”第 2 段:

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.

但是,我想知道 volatile unsigned char foo; 是否会调用未定义的行为?将 volatile 限定的变量存储在寄存器中似乎是不可能的。


还有,下面的代码是不是定义明确了?

unsigned char foo;
*&foo -= *&foo;

本题出自第102脚注:

102) ...... *&E is a function designator or an lvalue equal to E. ......

最佳答案

首先要澄清的是,6.3.2.1 中引用的部分解决了一种特殊情况,在这种情况下,您有一个未初始化的变量,该变量不一定分配在某个地址,因为该地址从未被占用。访问这样的对象是明确未定义的行为。这就是链接答案所关心的。

如果该特殊情况不适用,因为地址已被占用,则相关部分将为 6.7.9/10:

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

不确定值3.19.2的定义:

either an unspecified value or a trap representation

未指定值3.19.3的定义:

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

NOTE An unspecified value cannot be a trap representation.

最后说访问陷阱表示的部分是 UB,6.2.6.1/5,强调我的:

Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined.50) Such a representation is called a trap representation.

总而言之,不确定的值不一定是陷阱表示,因此访问未初始化的变量不一定是未定义的行为。


据我所知,标准中没有任何内容明确说明无符号字符不能包含陷阱表示。 6.2.6.2 只说他们不能有填充位。虽然在实践中这意味着 unsigned char 不能包含陷阱表示,因为为了这样做,它要么需要填充位,要么需要签名格式。所以在字里行间,我认为可以安全地假设 unsigned char 不能包含陷阱表示。


However, I wonder whether volatile unsigned char foo; invokes undefined behaviour?

声明一个变量永远不会调用其自身未定义的行为。如果您访问变量而不对其进行初始化,那么在正常情况下,该值将是不确定的。这是否是陷阱表示取决于实现。

但是,volatile 是一种特殊情况,所有这些都不适用。相反,你有 6.7.3/7:“......什么构成了对对象的访问具有 volatile 限定类型是实现定义的。”

所以它只是实现定义的行为。不分类型。


Also, is the following code well-defined?

unsigned char foo;
*&foo -= *&foo;

foo 有一个不确定的值。它的地址被占用了。因此,这是否是未定义的行为取决于不确定值是否是给定系统上的陷阱表示。如上所述,我不认为 unsigned char 可以作为陷阱表示。

但是您使用了 -= 运算符,这将使该表达式等同于

*&foo = *&foo - *&foo; 

二进制 - 运算符在计算期间将两个操作数提升为 int。如果一开始就没有陷阱表示,那么提升后的操作数中现在可能会有一些,它们是有符号类型的,可能带有填充位。

意味着这个特定的表达式可以调用未定义的行为。

关于c - 访问未初始化的变量时避免未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36531450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com