簡體   English   中英

reinterpret_cast unsigned char * as uint64_t * - 這是UB嗎?

[英]reinterpret_cast unsigned char* as uint64_t* - is this UB?

假設我們采用了unsigned char

std::array<uint8_t, 100500> blob;
// ... fill array ...

(注意:它已經對齊,問題不是關於對齊。)然后我們把它作為uint64_t[]並嘗試訪問它:

const auto ptr = reinterpret_cast<const uint64_t*>(blob.data());
std::cout << ptr[7] << std::endl;

轉向uint64_t然后從中讀取對我來說看起來很可疑。

但UBsan, -Wstrict-aliasing並沒有觸發它。 Google在FlatBuffers中使用此技術。 此外,Cap'n'Proto使用這個

是不確定的行為?

您無法通過其他類型的glvalue訪問unsigned char對象值。 但相反的是授權,您可以通過unsigned char glvalue [basic.lval]訪問任何對象的值:

如果程序試圖通過以下類型之一以外的glvalue訪問對象的存儲值,則行為未定義:[...]

  • charunsigned charstd​::​byte類型。

因此,要符合100%標准,我們的想法是顛倒reinterpret_cast

uint64_t i;
std::memcpy(&i, blob.data() + 7*sizeof(uint64_t), sizeof(uint64_t));
std::cout << i << std::endl;

它將產生完全相同的組件

轉換本身定義良好( reinterpret_cast永遠不會有UB),但如果在該地址中沒有構造uint64_t對象,則表達式“ ptr[7] ”中的左值轉換的左值將是UB。

由於未顯示“ // ... fill array ... ”,因此可能在該地址中構造了一個uint64_t對象(假設您所說的地址具有足夠的對齊):

const uint64_t* p = new (blob.data() + 7 * sizeof(uint64_t)) uint64_t();

如果在該地址中構造了uint64_t對象,則所討論的代碼具有明確定義的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM