C++中的UB(undefined behaviour)未定义行为
UB(undefined behaviour)未定义行为
https://blog.jqian.net/post/undefined-behavior.html
C/C++中常见的UB有:
- 整数溢出
- 序列点(Sequence Points)
- 违反了著名的Strict Aliasing规则
整数溢出
懂的都懂,整数看类型,浮点数遵循IEEE754规则(浮点并不是CPU硬件层面支持的,通常是int64,或者有编译过程中的自举(也或者不是,这块我真不是很清楚),好像跑题了,先到这)
序列点(Sequence Points)
顺序点:标准规定在两个序列点之间,程序可以任意顺序执行,这就给了编译器优化的空间。
副作用:例如赋值、自增等
i=5; j=(i++)+(i++);
最终结果是12、10、11都是可以的,甚至可能有其他结果。
本质上是因为在顺序点内部对一个变量两次赋值。两次自增操作出现在同一个表达式中,没有明确的顺序点(sequence point)来定义操作顺序。
结合性不发挥作用:只决定计算顺序,不决定副作用的应用顺序
strict aliasing(ANSI aliasing)
一个指针只能被dereferenced到相同或相兼容类型的对象上,也就是说不同类型的指针不会引用同一块内存区域(即aliasing)。
例:
uint32_t swap_words( uint32_t arg )
{
uint16_t* const sp = (uint16_t*)&arg; /* Error: undefined behavior */
uint16_t hi = sp[0];
uint16_t lo = sp[1];
sp[1] = hi;
sp[0] = lo;
return (arg);
}
当碰到这种不同类型cast的时候,最好的办法是使用void或char指针,并且借助于memcpy