C++ std::cmp_less 行为异常,__int128取决于标准编译器开关

c++ std::cmp_less misbehaving for __int128 depending on standard compiler switch

提问人:Ferenc Deak 提问时间:11/14/2023 更新时间:11/14/2023 访问量:51

问:

以下简短节目

#include <cstdint>
#include <utility>
#include <iostream>
int main() {
__int128 a = -1; 
__int128 b = 1; 
if (std::cmp_less(a, b)) { 
    std::cout << "less" << std::endl;
}
}

如果我使用(甚至)但失败或:-std=gnu++2b-std=gnu++20-std=c++20-std=c++23

In file included from <source>:2:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/utility: In instantiation of 'constexpr bool std::cmp_less(_Tp, _Up) [with _Tp = __int128; _Up = __int128]':
<source>:11:18:   required from here
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/utility:141:49: error: static assertion failed
  141 |       static_assert(__is_standard_integer<_Tp>::value);
      |                                                 ^~~~~
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/utility:141:49: note: 'std::integral_constant<bool, false>::value' evaluates to false
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/utility:142:49: error: static assertion failed
  142 |       static_assert(__is_standard_integer<_Up>::value);
      |                                                 ^~~~~
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/utility:142:49: note: 'std::integral_constant<bool, false>::value' evaluates to false
Compiler returned: 1

有人能解释一下为什么会发生这种情况吗?

https://gcc.godbolt.org/z/WYMjjsenP

C++ C++20 128

评论

2赞 273K 11/14/2023
__int128不是一个标准的类型名称,它是一个 GNU 扩展,保留给私人库使用。

答:

0赞 273K 11/14/2023 #1

由于不是标准的 C++ 整数类型,因此此类型没有模板重载。您可以添加此类重载。__int128std::cmp_less

#include <cstdint>
#include <iostream>
#include <utility>

template <>
bool std::cmp_less<__int128, __int128>(__int128 t, __int128 u) {
    return t < u;
}

int main() {
    __int128 a = -1;
    __int128 b = 1;

    if (std::cmp_less(a, b)) {
        std::cout << "less" << std::endl;
    }
}

https://gcc.godbolt.org/z/o3K9Yzfr4

如果要为不同的 类型添加重载,请参阅可能的实现示例。TU

0赞 Chris Dodd 11/14/2023 #2

__int128不是标准类型,所以当你处于严格的标准模式()时,它将不起作用。唯一令人惊讶的是,它没有在 和 的声明上给出错误。-std=c++20ab

正如你已经发现的那样,你需要启用GNU扩展(带有或类似)才能使其工作。-std=gnu++20