Home > Article > Backend Development > Why Does `int64_t` Behave Differently in 64-bit GCC Compiles?
Long Long Int vs. Long Int vs. Int64_t in C
C type traits can exhibit quirky behavior, particularly with signed 64-bit integer types. Here's an exploration of why:
In both 32-bit and 64-bit compiles (GCC and MSVC), the following program behaves as expected:
<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>
The output correctly indicates that int64_t, long int, and long long int are all equivalent 64-bit integer types.
However, a 64-bit GCC compile produces a different result:
int: 0 int64_t: 1 long int: 1 long long int: 0
This surprising behavior stems from the C standard library definition of int64_t:
<code class="cpp"># if __WORDSIZE == 64 typedef long int int64_t; # else __extension__ typedef long long int int64_t; # endif</code>
In a 64-bit compile, int64_t is defined as long int, not long long int. This means that the is_int64() template specialization that checks for int64_t will match long int instead of long long int.
Solution using Partial Template Specialization:
To address this issue, you can use partial template specialization to explicitly define is_int64() for long long int:
<code class="cpp">#if defined(__GNUC__) && (__WORDSIZE == 64) template <> bool is_int64<long long int>() { return true; } #endif</code>
However, this solution is dependent on the compiler and can be tedious to implement for every affected type.
Alternative Solution using Boost:
Boost provides a more elegant solution with the boost::is_same variadic template:
<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>
This approach will correctly identify all equivalent 64-bit integer types, regardless of their exact representation in the standard library.
The above is the detailed content of Why Does `int64_t` Behave Differently in 64-bit GCC Compiles?. For more information, please follow other related articles on the PHP Chinese website!