gpt4 book ai didi

c++ - FBString 的小字符串优化是否依赖未定义行为?

转载 作者:可可西里 更新时间:2023-11-01 15:53:09 25 4
gpt4 key购买 nike

Facebook 的 fbstring_core类使用 this talk 中描述的“小字符串优化”其中类数据成员的存储——Char*sizecapacity——将被重新用于存储字符数据,如果字符串足够小。用于区分这些情况的标志位位于“存储的最右边的字符”中。我的问题是,根据 C++11 标准,通过从未真正编写过的 bytes_ union 成员访问这些位是否构成未定义行为? Accessing inactive union member and undefined behavior?的答案表明它是。

以下摘录包含这些成员的声明以及用于确定此优化是否生效的 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_ 成员的字节。从上面链接的问题的答案中,我了解到这在 C99 中定义的行为,但在 C++11 中不是

最佳答案

这不仅看起来是 UB,而且完全没有必要,因为 bytes_ 的唯一用途似乎是读取 this 的最后一个字节,这可以在没有 UB 的情况下完成:

reinterpret_cast<const char*>(this)[sizeof(*this) - 1]

这要归功于 C++ 中的特殊豁免,它允许将对象重新解释为 char 数组。

关于c++ - FBString 的小字符串优化是否依赖未定义行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45900169/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com