关于 "object having more than one object representation" 的未指定行为
Unspecified behaviour about "object having more than one object representation"
仍在与 C (C99) 未定义和未指定的行为作斗争。
这次是以下未指定的行为(附件 J.1):
The representation used when storing a value in an object that has
more than one object representation for that value (6.2.6.1).
相应的第 6.2.6.1 节指出:
Where an operator is applied to a value that has more than one object
representation, which object representation is used shall not affect
the value of the result43). Where a value is stored in an object using
a type that has more than one object representation for that value, it
is unspecified which representation is used, but a trap representation
shall not be generated.
附注 43:
It is possible for objects x
and y
with the same effective type T
to
have the same value when they are accessed as objects of type T
, but
to have different values in other contexts. In particular, if ==
is
defined for type T
, then x == y
does not imply that memcmp(&x, &y, sizeof(T)) == 0
. Furthermore, x == y
does not necessarily imply that x
and y
have the same value; other operations on values of type T
may
distinguish between them.
我什至不明白什么是具有多个对象表示的值。它是否与 0(负零和正零)的浮点表示有关?
如您所料,-0.0
是一个不错的候选者,但仅适用于最后一个短语:
Furthermore, x == y
does not necessarily imply that x
and y
have the same value; other operations on values of type T
may distinguish between them.
double x = 0.0;
double y = -0.0;
if (x == y) {
printf("x and y have the same value\n");
}
if (memcmp(&x, &y, sizeof(double)) {
printf("x and y have a different representation\n");
}
if (1 / x != 1 / y) {
printf("1/x and 1/y have a different value\n");
}
具有多种可能表示的值的另一个示例是 NaN。 0.0 / 0.0
的计算结果为 NaN 值,该值可能与宏 NAN
或另一个产生 NaN 的操作产生的表示不同,甚至相同的表达式 0.0 / 0.0
再次计算。 memcmp()
可能表明表述不同。然而,这个例子并没有真正说明标准在问题中引用的目的,因为这些值与 ==
运算符不匹配。
你从附件 J 中引用的文本似乎专门针对一些罕见的架构(现在),这些架构具有填充位 and/or 负数表示和 0
的 2 种不同表示。所有现代系统都使用 two's complement to represent negative numbers, where all bit patterns represent different values, but 4 decades ago you some fairly common mainframes used ones' complement or sign and magnitude,其中 2 个不同的位模式可以表示值 0
.
I don't even understand what would be a value that has more than one object representation. Is it related for example to a floating point representation of 0 (negative and positive zero) ?
不是,负零和正零是不同的值。
在实践中,您可能不需要担心具有不同对象表示的值,但一个可能的示例将涉及包含填充位的整数类型。例如,假设您的实现提供了一个 15(值)位的无符号整数类型,其存储大小为 16 位。还假设出于评估对象的目的,该类型表示中的填充位被完全忽略(即,该类型不提供陷阱表示)。然后该类型可表示的每个值将有两个不同的对象表示,不同之处在于填充位的值。
标准规定,在这种情况下,您不能依赖于在任何给定情况下在这些值表示之间做出的特定选择,而且当此类对象是任何 C 运算符的操作数时也无关紧要.附注 43 阐明了这种差异可能会在其他方面感受到。
大多数这种语言都是 C 标准好,以允许在 Burroughs B 系列大型机上继续使用(AFAICT 仅 幸存的补码架构)。除非您必须使用那些或某些不常见的微控制器,或者您认真地进行逆向计算,否则您可以安全地假设整数类型的每个值只有一个对象表示,并且它们没有填充位。您还可以安全地假设所有整数类型都没有陷阱表示,除了您必须采用 J.2
的这一行
[the behavior is undefined if ...] the value of an object with automatic storage duration is used while it is indeterminate
就好像它是规范的,就好像划掉的词不存在一样。 (仔细阅读实际的规范文本并不支持这条规则,但它仍然是当前所有优化编译器所采用的规则。)
可以在现代的、非奇特的实现中具有多个值的对象表示的具体示例包括:
_Bool
:未指定用适当大小的 0 或 1 以外的整数值表示覆盖 _Bool
对象的效果。
指针类型:一些架构忽略指向最小对齐大于1的类型的指针的低位(例如(int*)0x8000_0000
和(int*)0x8000_0001
可能被视为指代相同的 int
对象;这是一项有意的硬件功能,便于使用标记指针)
浮点类型:IEC 60559 允许硬件对 NaN 的所有许多表示进行相同的处理(并可能压缩在一起)。 (注意:+0 和 −0 是 IEEE 浮点数中的不同值,不是相同值的不同表示。)
这些也是在现代实现中可以具有陷阱表示的标量类型。特别是,附件 F 明确声明发信号 NaN 的行为未定义,即使它在 IEC 60559 的抽象实现中有明确定义。
仍在与 C (C99) 未定义和未指定的行为作斗争。
这次是以下未指定的行为(附件 J.1):
The representation used when storing a value in an object that has more than one object representation for that value (6.2.6.1).
相应的第 6.2.6.1 节指出:
Where an operator is applied to a value that has more than one object representation, which object representation is used shall not affect the value of the result43). Where a value is stored in an object using a type that has more than one object representation for that value, it is unspecified which representation is used, but a trap representation shall not be generated.
附注 43:
It is possible for objects
x
andy
with the same effective typeT
to have the same value when they are accessed as objects of typeT
, but to have different values in other contexts. In particular, if==
is defined for typeT
, thenx == y
does not imply thatmemcmp(&x, &y, sizeof(T)) == 0
. Furthermore,x == y
does not necessarily imply thatx
andy
have the same value; other operations on values of typeT
may distinguish between them.
我什至不明白什么是具有多个对象表示的值。它是否与 0(负零和正零)的浮点表示有关?
如您所料,-0.0
是一个不错的候选者,但仅适用于最后一个短语:
Furthermore,
x == y
does not necessarily imply thatx
andy
have the same value; other operations on values of typeT
may distinguish between them.
double x = 0.0;
double y = -0.0;
if (x == y) {
printf("x and y have the same value\n");
}
if (memcmp(&x, &y, sizeof(double)) {
printf("x and y have a different representation\n");
}
if (1 / x != 1 / y) {
printf("1/x and 1/y have a different value\n");
}
具有多种可能表示的值的另一个示例是 NaN。 0.0 / 0.0
的计算结果为 NaN 值,该值可能与宏 NAN
或另一个产生 NaN 的操作产生的表示不同,甚至相同的表达式 0.0 / 0.0
再次计算。 memcmp()
可能表明表述不同。然而,这个例子并没有真正说明标准在问题中引用的目的,因为这些值与 ==
运算符不匹配。
你从附件 J 中引用的文本似乎专门针对一些罕见的架构(现在),这些架构具有填充位 and/or 负数表示和 0
的 2 种不同表示。所有现代系统都使用 two's complement to represent negative numbers, where all bit patterns represent different values, but 4 decades ago you some fairly common mainframes used ones' complement or sign and magnitude,其中 2 个不同的位模式可以表示值 0
.
I don't even understand what would be a value that has more than one object representation. Is it related for example to a floating point representation of 0 (negative and positive zero) ?
不是,负零和正零是不同的值。
在实践中,您可能不需要担心具有不同对象表示的值,但一个可能的示例将涉及包含填充位的整数类型。例如,假设您的实现提供了一个 15(值)位的无符号整数类型,其存储大小为 16 位。还假设出于评估对象的目的,该类型表示中的填充位被完全忽略(即,该类型不提供陷阱表示)。然后该类型可表示的每个值将有两个不同的对象表示,不同之处在于填充位的值。
标准规定,在这种情况下,您不能依赖于在任何给定情况下在这些值表示之间做出的特定选择,而且当此类对象是任何 C 运算符的操作数时也无关紧要.附注 43 阐明了这种差异可能会在其他方面感受到。
大多数这种语言都是 C 标准好,以允许在 Burroughs B 系列大型机上继续使用(AFAICT 仅 幸存的补码架构)。除非您必须使用那些或某些不常见的微控制器,或者您认真地进行逆向计算,否则您可以安全地假设整数类型的每个值只有一个对象表示,并且它们没有填充位。您还可以安全地假设所有整数类型都没有陷阱表示,除了您必须采用 J.2
的这一行[the behavior is undefined if ...] the value of an object
with automatic storage durationis used while it is indeterminate
就好像它是规范的,就好像划掉的词不存在一样。 (仔细阅读实际的规范文本并不支持这条规则,但它仍然是当前所有优化编译器所采用的规则。)
可以在现代的、非奇特的实现中具有多个值的对象表示的具体示例包括:
_Bool
:未指定用适当大小的 0 或 1 以外的整数值表示覆盖_Bool
对象的效果。指针类型:一些架构忽略指向最小对齐大于1的类型的指针的低位(例如
(int*)0x8000_0000
和(int*)0x8000_0001
可能被视为指代相同的int
对象;这是一项有意的硬件功能,便于使用标记指针)浮点类型:IEC 60559 允许硬件对 NaN 的所有许多表示进行相同的处理(并可能压缩在一起)。 (注意:+0 和 −0 是 IEEE 浮点数中的不同值,不是相同值的不同表示。)
这些也是在现代实现中可以具有陷阱表示的标量类型。特别是,附件 F 明确声明发信号 NaN 的行为未定义,即使它在 IEC 60559 的抽象实现中有明确定义。