long long int vs. long int vs. int64_t in C
Consider the following C program:
<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>
In both 32-bit GCC and 32/64-bit MSVC compiles, the output of the program will be:
int: 0 int64_t: 1 long int: 0 long long int: 1
However, in a 64-bit GCC compile, the output will change to:
int: 0 int64_t: 1 long int: 1 long long int: 0
This behavior arises because in 64-bit compiles, int64_t is defined as long int, not long long int. To fix this, we can use platform-specific checks as follows:
<code class="cpp">#if defined(__GNUC__) && (__WORDSIZE == 64) template <> bool is_int64<long long int>() { return true; } #endif</code>
However, this solution is not ideal, as it relies on specific compiler and platform combinations. A more reliable method would be to explicitly specify the type equivalence to the compiler. Unfortunately, C does not provide a way to define such equivalence between basic data types. Instead, we can rely on type traits, such as std::is_same. For example:
<code class="cpp">// C++11 template <typename T> void same_type(T, T) {} void foo() { long int x; long long int y; same_type(x, y); // Will now compile successfully }</code>
In this example, std::is_same is used to determine whether x and y have the same type, regardless of their underlying representation.
The above is the detailed content of Why Does the Behavior of `int64_t`, `long int`, and `long long int` Differ in 32-bit and 64-bit Compilers?. For more information, please follow other related articles on the PHP Chinese website!