C++中的UB(undefined behaviour)未定義行為

真昼小天使daisuki發表於2024-12-09

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

相關文章