C 中的 Long Long Int 与 Long Int 与 Int64_t
C 类型特征可能会表现出古怪的行为,特别是在有符号 64 位的情况下整数类型。下面是对原因的探索:
在 32 位和 64 位编译(GCC 和 MSVC)中,以下程序的行为符合预期:
<code class="cpp">#include <iostream> #include <cstdint> template <typename T> bool is_int64() { return false; } template <> bool is_int64<int64_t>() { return true; } int main() { std::cout << "int:\t" << is_int64<int>() << std::endl; std::cout << "int64_t:\t" << is_int64<int64_t>() << std::endl; std::cout << "long int:\t" << is_int64<long int>() << std::endl; std::cout << "long long int:\t" << is_int64<long long int>() << std::endl; return 0; }</code>
输出正确表明 int64_t 、long int 和 long long int 都是等效的 64 位整数类型。
但是,64 位 GCC 编译会产生不同的结果:
int: 0 int64_t: 1 long int: 1 long long int: 0
这种令人惊讶的行为源于int64_t 的 C 标准库定义:
<code class="cpp"># if __WORDSIZE == 64 typedef long int int64_t; # else __extension__ typedef long long int int64_t; # endif</code>
在 64 位编译中,int64_t 被定义为 long int,而不是 long long int。这意味着检查 int64_t 的 is_int64() 模板特化将匹配 long int 而不是 long long int。
使用部分模板特化的解决方案:
解决此问题问题,您可以使用部分模板专门化为 long long int 显式定义 is_int64():
<code class="cpp">#if defined(__GNUC__) && (__WORDSIZE == 64) template <> bool is_int64<long long int>() { return true; } #endif</code>
但是,此解决方案依赖于编译器,并且对于每种受影响的类型实现起来可能很繁琐。
使用 Boost 的替代解决方案:
Boost 使用 boost::is_same 可变参数模板提供了更优雅的解决方案:
<code class="cpp">#include <boost/type_traits/is_same.hpp> template <typename T> bool is_int64_boost() { return boost::is_same<T, int64_t>::value; } int main() { std::cout << "int:\t" << is_int64_boost<int>() << std::endl; std::cout << "int64_t:\t" << is_int64_boost<int64_t>() << std::endl; std::cout << "long int:\t" << is_int64_boost<long int>() << std::endl; std::cout << "long long int:\t" << is_int64_boost<long long int>() << std::endl; return 0; }</code>
此方法将正确识别所有等效的 64 位整数类型,无论它们在标准库中的确切表示形式如何。
以上是为什么 `int64_t` 在 64 位 GCC 编译中表现不同?的详细内容。更多信息请关注PHP中文网其他相关文章!