Facebook'un fbstring_core sınıf sınıfının veri üyeleri için depolama burada this talk anlatıldığı "Küçük dize Optimizasyonu" kullanır. Bu durumlar arasında ayrım yapmak için kullanılan bayrak bitleri, "depolamanın en sağdaki karakterinde" bulunur. Sorum şu ki, bu bitlere hiçbir zaman gerçekten yazılmamış olan bytes_
sendika üyesine ulaşıp ulaşamayacağınız, C++ 11 standardı başına tanımlanmamış bir davranış mı oluşturuyor? Accessing inactive union member and undefined behavior? cevabı, bunu önerdi.FBString'in küçük dize eniyilemesi tanımsız davranışa dayanıyor mu? Bir <code>Char*</code>, <code>size</code> ve <code>capacity</code> - - dize yeterince küçükse mağaza karakter verilerine başka bir amaca uygun olacaktır
Aşağıdaki alıntı, bu üyelerin bildirimini ve bu optimizasyonun etkin olup olmadığını belirlemek için kullanılan category()
üye işlevini içerir.
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_;
};
uygulama aslında size_t capacity_
üyesinin parçası olabilecek bir bayt erişmek için "tip cinaslı" seçeneğini kullanarak dayanıyor gibi görünüyor. Yukarıda bağlantılı soruya verilen yanıttan, bu 'un C99'da tanımlanmış davranışı olduğunu, ancak C++ 11'de değil mi?
reinterpret_cast<const char*>(this)[sizeof(*this) - 1]
var:
Herhangi bir imzanın "karakterine" erişim her zaman izin verilir. – o11c
Boost'taki benzer bir kod, bir hatayla sonuçlandı: https://svn.boost.org/trac10/ticket/12183 –
@ o11c: '' uint8_t' '' 'char'' türü için bir takma ad olarak tanımlandı mı? Yine de? 'İmzasız char'' kullanmak daha güvenli görünüyor. –