簡體   English   中英

FBString的小字符串優化是否依賴於未定義的行為?

[英]Does FBString's small string optimization rely on undefined behavior?

Facebook的fbstring_core類使用本講座中描述的“小字符串優化”,其中類的數據成員的存儲 - Char*sizecapacity - 將被重新用於存儲字符數據(如果字符串足夠小)。 用於區分這些情況的標志位位於“存儲器的最右邊的字符”中。 我的問題是,是否通過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.

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