C++核心準則C.183: 不要使用聯(lián)合體實現(xiàn)雙關(guān)類型

C.183: Don't use a?union?for type punning
C.183: 不要使用聯(lián)合體實現(xiàn)雙關(guān)類型
Reason(原因)
It is undefined behavior to read a?union?member with a different type from the one with which it was written. Such punning is invisible, or at least harder to spot than using a named cast. Type punning using a?union?is a source of errors.
向聯(lián)合體的一個類型的成員寫入,然后從聯(lián)合體不同類型的另一個成員讀出數(shù)據(jù)的行為是沒有定義的。這樣的雙關(guān)性操作無法發(fā)現(xiàn),或者至少比使用命名轉(zhuǎn)換更難發(fā)現(xiàn)。使用聯(lián)合體實現(xiàn)雙關(guān)類型是錯誤的源頭。
Example, bad(反面示例)
union Pun {
int x;
unsigned char c[sizeof(int)];
};
The idea of?Pun?is to be able to look at the character representation of an?int.
Pun的想法是可以觀察整數(shù)的字節(jié)表現(xiàn)。
void bad(Pun& u)
{
u.x = 'x';
cout << u.c[0] << '\n'; // undefined behavior
}
If you wanted to see the bytes of an?int, use a (named) cast:
如果你希望看到整數(shù)的各個字節(jié),使用(命名)轉(zhuǎn)換:
void if_you_must_pun(int& x)
{
auto p = reinterpret_cast(&x);
cout << p[0] << '\n'; // OK; better
// ...
}
Accessing the result of an?reinterpret_cast?to a different type from the objects declared type is defined behavior (even though?reinterpret_cast?is discouraged), but at least we can see that something tricky is going on.
使用reinterpret_case將一個對象從它被定義的類轉(zhuǎn)換為不同的類型之后訪問其結(jié)果是被定義的行為(即使是這樣也不推薦使用reinterpret_cast),但是至少我們可以看到某些危險的處理正在進行。
Note(注意)
Unfortunately,?unions are commonly used for type punning. We don't consider "sometimes, it works as expected" a strong argument.
C++17 introduced a distinct type?std::byte?to facilitate operations on raw object representation. Use that type instead of?unsigned char?or?char?for these operations.
不幸的是,聯(lián)合體經(jīng)常被用于雙關(guān)類型。我們不認為“有時會按照預期動作”是一個很有力的觀點。C++17引入了新類型std::byte以協(xié)助表現(xiàn)針對原始對象的操作。在這些操作中應該使用std::byte而不是unsigned char。
Enforcement(注意)
???
原文鏈接:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c183-dont-use-a-union-for-type-punning
覺得本文有幫助?請分享給更多人。
關(guān)注【面向?qū)ο笏伎肌枯p松學習每一天!
面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>
