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

posted @ 2024-12-09 02:11  真昼小天使daisuki  阅读(14)  评论(0编辑  收藏  举报