陷阱表示与未指定值之间的区别是什么?

时间:2015-11-14 02:22:23

标签: c language-lawyer c11

在3.19.3 p1中,C11表示未指定的值不能成为陷阱表示,但我不明白哪个值不是陷阱表示,也不是未指定。

BTW,我也想知道编译器如何知道对象表示是否是陷阱表示?

2 个答案:

答案 0 :(得分:3)

控制与数据之间的区别。

未指定的值可能导致结果中出现意外值(函数返回,全局变量赋值等)。但是仍然会遵循程序的正常控制流程。

另一方面,陷阱表示可能导致使用分支语句(函数调用,条件,循环,gotos,返回)没有描述的控制流。

一个典型的例子是IEEE 754中的信令NaN。根据FPU控制字,遇到信令NaN会导致立即转移到异常处理程序(也就是软件中断又称信号)。

答案 1 :(得分:1)

条款的定义

未指明的行为 - 行为,对于正确的程序构造和正确的数据,标准没有要求。

未定义的行为 - 在使用不可移植或错误的程序构造时,对错误数据或不确定值对象的行为,标准没有要求

  

在构造const对象期间,如果是对象的值   或者通过不是的glvalue访问它的任何子对象   直接或间接地从构造函数的this指针获取,   由此获得的对象或子对象的值未指定。

struct C;
void no_opt(C*);

struct C {
    int c;
    C() : c(0) { no_opt(this); }
};

const C cobj;

void no_opt(C* cptr) {
    int i = cobj.c * 100; // value of cobj.c is unspecified
    cptr->c = 1;
    cout << cobj.c * 100 // value of cobj.c is unspecified
         << ’\n’;
}

在上面的示例中,没有未初始化的值,因此没有陷阱表示,但标准不会授予(指定)其行为。允许上面例子中的编译器做任何事情,即不同的编译器会给出不同的结果。

  

英语术语或多或少逐字使用:&#34;未指定&#34;手段   精确的语义不是由标准给出的,而是标准的   程序不会变得不明确或形成不良。

     

陷阱表示是一组位,当被解释为a时   特定类型的值,导致未定义的行为。陷阱   表示最常见于浮点和指针   价值,但从理论上讲,几乎任何类型都可能有陷阱   表示。未初始化的对象可能会占用陷阱   表示。这提供了与旧规则相同的行为:访问   未初始化的对象会产生未定义的行为。

采用以下示例:

unsigned char a, b;
memcpy(&a, &b, 1);
a -= a;
  • 这里采用了ab的地址,因此它们的价值就是不确定的。
  • 由于unsigned char永远不会有陷阱表示,不确定值是未指定的,因此unsigned char的任何值都可能发生。
  • 最后a必须保留值0

ab有未指定的值:

  

3.19.3未指定值

     

相关类型的有效值,其中本国际标准没有规定在任何情况下选择哪个值