请教关于陷阱表示。

陷阱表示。

  1. 什么是C中的“陷阱表示”(一些例子可能有帮助)?这适用于C ++吗?

  2. 鉴于此代码......

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

    ...并假设sizeof(int) == sizeof(float)f并且*pi具有相同的二进制表示/模式?



幕布斯6054654
浏览 406回答 3
3回答

智慧大石

陷阱表示是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不会这样对待它们,但编译器可能会。)您显示的代码具有未定义的行为,但这是因为指针别名规则,而不是因为陷阱表示。这是如何将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)。

精慕HU

使用指向int的别名浮点数的未定义行为。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JQuery