Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 未指明的行为;具有多个对象表示形式的对象”;_C_C99_Unspecified Behavior - Fatal编程技术网

C 未指明的行为;具有多个对象表示形式的对象”;

C 未指明的行为;具有多个对象表示形式的对象”;,c,c99,unspecified-behavior,C,C99,Unspecified Behavior,仍在与C(C99)未定义和未指定的行为作斗争 这一次是以下未指明的行为(附录J.1): 将值存储在具有 该值的多个对象表示形式(6.2.6.1) 相应的第6.2.6.1节规定: 其中运算符应用于具有多个对象的值 表示,所使用的对象表示不应影响 结果的值43)。将值存储在对象中时使用 对于该值具有多个对象表示形式的类型,它 未指定使用哪种表示法,而是陷阱表示法 不应生成 注43: 具有相同有效类型T的对象x和y可以 当它们作为T类型的对象访问时,具有相同的值,但 在其他上下文中具有不同的值。特别是

仍在与C(C99)未定义和未指定的行为作斗争

这一次是以下未指明的行为(附录J.1):

将值存储在具有 该值的多个对象表示形式(6.2.6.1)

相应的第6.2.6.1节规定:

其中运算符应用于具有多个对象的值 表示,所使用的对象表示不应影响 结果的值43)。将值存储在对象中时使用 对于该值具有多个对象表示形式的类型,它 未指定使用哪种表示法,而是陷阱表示法 不应生成

注43:

具有相同有效类型
T
的对象
x
y
可以 当它们作为
T
类型的对象访问时,具有相同的值,但 在其他上下文中具有不同的值。特别是,如果
==
是 为类型
T
定义,则
x==y
并不意味着
memcmp(&x,&y,sizeof(T))==0
。此外,
x==y
并不一定意味着
x
y
具有相同的值;可以对
T
类型的值执行其他操作 区分它们


我甚至不知道有多个对象表示的值是什么。例如,它是否与0(负零和正零)的浮点表示法有关?

正如您所怀疑的,
-0.0
是一个很好的候选者,但仅适用于最后一个短语:

此外,
x==y
并不一定意味着
x
y
具有相同的值;对
T
类型的值的其他操作可能会区分它们

具有多个可能表示形式的值的另一个示例是NaN
0.0/0.0
计算为NaN值,该值可能与宏
NaN
或另一个生成NaN的操作产生的值不同,或者甚至与再次计算的表达式
0.0/0.0
相同
memcmp()
可能表明表示方式不同。然而,该示例并未真正说明问题中标准引用的目的,因为这些值与
=
运算符不匹配

您从附录J中引用的文本似乎专门针对一些罕见的体系结构(现在),这些体系结构具有填充位和/或负数表示形式,并具有两种不同的
0
表示形式。所有现代系统都用来表示负数,其中所有位模式表示不同的值,但40年前,您使用了一些相当常见的大型机,或者两种不同的位模式可以表示值
0

我甚至不知道有多个对象表示的值是什么。例如,它是否与0(负零和正零)的浮点表示有关

不,负零和正零是不同的值

实际上,您可能不需要担心具有不同对象表示形式的值,但一个可能的示例涉及包含填充位的整数类型。例如,假设您的实现提供了一个15(值)位无符号整数类型,其存储大小为16位。还假设为了计算对象,完全忽略了该类型表示中的填充位(即,该类型不提供陷阱表示)。然后,由该类型表示的每个值将有两个不同的对象表示,填充位的值不同


该标准指出,在这种情况下,您不能依赖于在任何给定情况下在这些值表示形式之间做出的特定选择,但当这些对象是任何C运算符的操作数时,这并不重要。注43阐明了这种差异可能在其他方面也能感受到。

这种语言的大部分是C标准,它非常适合在Burroughs B系列大型机上继续使用(AFAICT是唯一幸存的补充体系结构)。除非您必须使用这些,或者某些不常见的微控制器,或者您非常喜欢逆向计算,否则您可以安全地假设整数类型每个值只有一个对象表示,并且它们没有填充位。您还可以安全地假设所有整数类型都没有陷阱表示,除非您必须采用J.2的这一行

[如果…,则行为未定义]具有自动存储持续时间的对象的值在不确定时使用

好像它是规范性的,好像被划掉的单词不存在。(仔细阅读实际规范性文本不支持此规则,但它仍然是当前所有优化编译器采用的规则。)

在现代、非异国情调的实现中,一个值可以有多个对象表示的类型的具体示例包括:

  • \u Bool
    :未指定用整数值表示而不是适当大小的0或1覆盖
    \u Bool
    对象的效果

  • 指针类型:某些体系结构忽略指向最小对齐度大于1的类型的指针的低位(例如,
    (int*)0x8000_0000
    (int*)0x8000_0001
    可能被视为引用相同的
    int
    对象;这是一种有意的硬件功能,便于使用标记指针)

  • 浮点类型:IEC 60559允许硬件以相同的方式处理NaN的所有表示(并可能挤压在一起)。(注:+0和−
    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");
    }