在3.19.3 p1中,C11表示未指定的值不能成为陷阱表示,但我不明白哪个值不是陷阱表示,也不是未指定。
BTW,我也想知道编译器如何知道对象表示是否是陷阱表示?
答案 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;
a
和b
的地址,因此它们的价值就是不确定的。unsigned char
永远不会有陷阱表示,不确定值是未指定的,因此unsigned char
的任何值都可能发生。a
必须保留值0
。 a
和b
有未指定的值:
3.19.3未指定值
相关类型的有效值,其中本国际标准没有规定在任何情况下选择哪个值