陷阱重新presentation [英] trap representation

查看:140
本文介绍了陷阱重新presentation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 什么是C陷重新presentation(一些例子可以帮助)?这是否适用于C ++?

     浮动F = 3.5;
    INT * PI =(INT *)及F;


  2. 编辑:我知道圆周率违反规则走样,按照C标准UB它。 ATLEAST对GCC它产生的任何错误,但警告。在此实现(即GCC),假定的sizeof(int)的==的sizeof(浮动)不要˚F * PI 具有相同的二进制重新presentation /模式?有关MSVC什么?


解决方案

  1. 一个陷阱再presentation是使用C99(IIRC不是C89)来描述放入一个类型所占用的空间位模式,但引发未定义行为一个包罗万象的词如果作为该类型的值。该定义是在第6.2.6.1p5(带触角伸向所有的6.2.6),我不会因为它的长和困惑在这里引用一下。对于此种位模式存在A型被认为有陷阱重新presentations。任何类型的要求有任何陷阱重新presentations,但唯一类型的标准保证会的的有陷阱重新presentations是 unsigned char型(6.2.6.1p5,6.2.6.2p1)。

    该标准给出了陷阱重新presentations,两者都不符合任何任何真正的CPU已经做过多年的两个假设的例子,所以我不打算跟他们迷惑你。 A 的例子陷阱重新presentation(也的的只是有资格,你有可能任何CPU的硬件级的陷阱再度presentation 的东西遭遇)是一个浮点类型的信令NaN的。 C99附件F(2.1节)明确叶信号NaN未定义的行为,即使IEC 60559规定了详细的行为。

    值得一提的是,虽然指针类型的的允许有陷阱重新presentations,空指针的的陷阱再度presentations。空指针只因为如果它们被解除引用或抵消不确定的行为;对它们的其他操作(最重要的是,比较和拷贝)被明确定义。陷阱重新presentations导致未定义的行为,如果你仅仅是使用具有陷阱重新presentation类型读的他们。 (无论的无效的但非空指针,否则应,考虑重新陷阱presentations是一个有争议的话题。CPU不对待他们的方式,但是编译器可能。)


  2. 在code你展示了未定义的行为,但这是因为陷阱重新presentations不是因为指针别名规则。这是怎样一个浮动转换 INT 用相同的重新presentation(假设,就像你说的,的sizeof(浮点)==的sizeof(INT)

      INT extract_int(浮点六)
    {
        工会{INT I;浮F; } U;
        u.f = F;
        返回u.i;
    }

    这code具有的未指定的(而不是未定义)的C99,这基本上意味着该标准没有定义的什么整数值的产生,但你的行为得到的部分的有效的整数值,它不是一个陷阱重新presentation,编译器是不允许的,你有没有做过这样的假设进行优化。 (6.2.6.1节,第7,我C99的副本可能包括技术corrigienda - 我的记忆是,这的的未定义的原始出版物,但是被改变非特定的TC)。


  1. What is trap representation in C (some examples might help)? Does this apply to C++?

    float f=3.5;
    int *pi = (int*)&f;
    

  2. Edit: I know 'pi' violates aliasing rule and it is UB according to C standard. Atleast on GCC it produces no errors, but warnings. In this implementation (i.e., GCC), assuming sizeof(int) == sizeof(float) do f and *pi have the same binary representation/pattern? What about MSVC?

解决方案

  1. A trap representation is a catch-all term used by C99 (IIRC not by C89) to describe bit patterns that fit into the space occupied by a type, but trigger undefined behavior if used as a value of that type. The definition is in section 6.2.6.1p5 (with tentacles into all of 6.2.6) and I'm not going to quote it here because it's long and confusing. A type for which such bit patterns exist is said to "have" trap representations. No type is required to have any trap representations, but the only type that the standard guarantees will not have trap representations is unsigned char (6.2.6.1p5, 6.2.6.2p1).

    The standard gives two hypothetical examples of trap representations, neither of which correspond to anything that any real CPU has done for many years, so I'm not going to confuse you with them. A good example of a trap representation (also the only thing that qualifies as a hardware-level trap representation on any CPU you are likely to encounter) is a signaling NaN in a floating-point type. C99 Annex F (section 2.1) explicitly leaves the behavior of signaling NaNs undefined, even though IEC 60559 specifies their behavior in detail.

    It's worth mentioning that, while pointer types are allowed to have trap representations, null pointers are not trap representations. Null pointers only cause undefined behavior if they are dereferenced or offset; other operations on them (most importantly, comparisons and copies) are well-defined. Trap representations cause undefined behavior if you merely read them using the type that has the trap representation. (Whether invalid but non-null pointers are, or should be, considered trap representations is a subject of debate. The CPU doesn't treat them that way, but the compiler might.)

  2. The code you show has undefined behavior, but this is because of the pointer-aliasing rules, not because of trap representations. This is how to convert a float into the int with the same representation (assuming, as you say, sizeof(float) == sizeof(int))

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

    This code has unspecified (not undefined) behavior in C99, which basically means the standard doesn't define what integer value is produced, but you do get some valid integer value, it's not a trap representation, and the compiler is not allowed to optimize on the assumption that you have not done this. (Section 6.2.6.1, para 7. My copy of C99 might include technical corrigienda — my recollection is that this was undefined in the original publication but was changed to unspecified in a TC.)

这篇关于陷阱重新presentation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆