簡體   English   中英

static_assert 表達式不是帶有 __builtin_clz 的整數常量表達式

[英]static_assert expression is not an integral constant expression with __builtin_clz

我有以下代碼:

typedef unsigned char uchar;

constexpr int leaing_ones(uchar const u8) noexcept {
  return __builtin_clz(static_cast<uchar>(~static_cast<unsigned>(u8))) +
         sizeof(uchar) * 8 - sizeof(int) * 8;
}

int main() {
  static_assert(leaing_ones(0b0000'0000) == 0);
  static_assert(leaing_ones(0b1000'0000) == 1);
  static_assert(leaing_ones(0b1100'0000) == 2);
  static_assert(leaing_ones(0b1110'0000) == 3);
  static_assert(leaing_ones(0b1111'0000) == 4);
  static_assert(leaing_ones(0b1111'1000) == 5);
  static_assert(leaing_ones(0b1111'1000) == 5);
  static_assert(leaing_ones(0b1111'1100) == 6);
  static_assert(leaing_ones(0b1111'1110) == 7);
  static_assert(leaing_ones(0b1111'1111) == 8);
}

我用 clang 12 和 GCC 11.1測試了這些。 唯一的問題是 clang 特別不喜歡最后一個斷言:

<source>:16:17: error: static_assert expression is not an integral constant expression
  static_assert(leaing_ones(0b1111'1111) == 8);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

據我所知,我沒有引起任何溢出,並且 GCC 與所有這些都可以正常工作。 這是 clang 錯誤,還是我忽略了什么?

0傳遞給__builtin_clz是 UB。

來自GCC 手冊

返回 x 中前導 0 位的數量,從最高有效位 position 開始。 如果 x 為 0,則結果未定義。

(我的粗體)

__builtin_clz對於值為 zero 的參數是未定義的,並且由於您反轉所有位, 0b1111'1111成為全零的模式。 您的 function 需要特殊情況0才能使用適當的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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