[英]Does FBString's small string optimization rely on undefined behavior?
Facebook的fbstring_core類使用本講座中描述的“小字符串優化”,其中類的數據成員的存儲 - Char*
, size
和capacity
- 將被重新用於存儲字符數據(如果字符串足夠小)。 用於區分這些情況的標志位位於“存儲器的最右邊的字符”中。 我的問題是,是否通過bytes_
union成員訪問這些位(從未實際編寫過)是否構成了C ++ 11標准的未定義行為? 訪問非活動聯盟成員和未定義行為的答案? 表明它是。
以下摘錄包含這些成員的聲明以及用於確定此優化是否有效的category()
成員函數。
typedef uint8_t category_type;
enum class Category : category_type {
isSmall = 0,
isMedium = kIsLittleEndian ? 0x80 : 0x2,
isLarge = kIsLittleEndian ? 0x40 : 0x1,
};
Category category() const {
// works for both big-endian and little-endian
return static_cast<Category>(bytes_[lastChar] & categoryExtractMask);
}
struct MediumLarge {
Char * data_;
size_t size_;
size_t capacity_;
size_t capacity() const {
return kIsLittleEndian
? capacity_ & capacityExtractMask
: capacity_ >> 2;
}
void setCapacity(size_t cap, Category cat) {
capacity_ = kIsLittleEndian
? cap | (static_cast<size_t>(cat) << kCategoryShift)
: (cap << 2) | static_cast<size_t>(cat);
}
};
union {
uint8_t bytes_[sizeof(MediumLarge)]; // For accessing the last byte.
Char small_[sizeof(MediumLarge) / sizeof(Char)];
MediumLarge ml_;
};
似乎這個實現依賴於使用“類型雙關語”來訪問實際上可能是size_t capacity_
member的一部分的字節。 從問題的答案上面鏈接,據我了解,這是 C99定義的行為,而不是在C ++ 11?
不僅那些看起來UB,這是完全沒有必要的,因為只有使用bytes_
似乎是閱讀的最后一個字節this
,可以在不UB來完成:
reinterpret_cast<const char*>(this)[sizeof(*this) - 1]
這要歸功於C ++中的特殊豁免,它允許將對象重新解釋為char數組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.