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

陷阱表示。

陷阱表示。

C++ C
GCT1015 2019-07-24 15:01:45
陷阱表示。什么是C中的“陷阱表示”(一些例子可能有帮助)?这适用于C ++吗?鉴于此代码......float f=3.5;int *pi = (int*)&f;...并假设sizeof(int) == sizeof(float),f并且*pi具有相同的二进制表示/模式?
查看完整描述

3 回答

?
桃花长相依

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

  1. 陷阱表示是C99(IIRC而不是C89)用来描述适合类型占用空间的位模式的全部术语,但如果用作该类型的值,则触发未定义的行为。定义见6.2.6.1p5(6.2.6中的所有内容都有触角),我不打算在这里引用它,因为它很长而且令人困惑。存在这种位模式的类型被称为“具有”陷阱表示。没有类型需要任何陷阱表示,但标准保证具有陷阱表示的唯一类型是unsigned char(6.2.6.1p5,6.2.6.2p1)。

    该标准给出了陷阱表示的两个假设示例,这两个示例都不对应任何真实CPU多年来所做的任何事情,因此我不会将您与它们混淆。陷阱表示的一个很好的例子(也是唯一可以作为您可能遇到的任何CPU上的硬件级陷阱表示的东西)是浮点类型的信令NaN。C99附件F(第2.1节)明确地将信令NaN的行为定义为未定义,即使IEC 60559详细说明了它们的行为。

    值得一提的是,当指针类型允许有陷阱表示,空指针是不是陷阱表示。如果取消引用或偏移,则空指针仅导致未定义的行为; 对它们的其他操作(最重要的是,比较和复制)是明确定义的。如果仅使用具有陷阱表示的类型读取陷阱表示,则陷阱表示会导致未定义的行为。(无效但非空指针是否应该被认为是陷阱表示是一个争论的主题.CPU不会这样对待它们,但编译器可能会。)

  2. 您显示的代码具有未定义的行为,但这是因为指针别名规则,而不是因为陷阱表示。这是如何将a float转换为int具有相同的表示(假设,如你所说sizeof(float) == sizeof(int)

    int extract_int(float f){
        union { int i; float f; } u;
        u.f = f;
        return u.i;}

    此代码在C99中具有未指定(未定义)的行为,这基本上意味着标准不定义生成的整数值,但是您确实获得了一些有效的整数值,它不是陷阱表示,并且不允许编译器进行优化假设你还没有这样做。(6.2.6.1节,第7,我的C99的副本可能包括技术corrigienda -我的回忆是,这在原来的出版物不确定,但改为不确定的TC)。


查看完整回答
反对 回复 2019-07-24
?
慕神8447489

TA贡献1780条经验 获得超1个赞

使用指向int的别名浮点数的未定义行为。


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

添加回答

举报

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