Home  >  Article  >  Backend Development  >  Why does `long int` sometimes behave like `int64_t` in C ?

Why does `long int` sometimes behave like `int64_t` in C ?

Barbara Streisand
Barbara StreisandOriginal
2024-10-30 22:45:18444browse

Why does `long int` sometimes behave like `int64_t` in C  ?

Long Long Int vs. Long Int vs. Int64_t in C

While using C type traits, some peculiar behavior can be encountered. Consider the following program:

<code class="c++">#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 32-bit compiles, the output is as expected:

int:           0
int64_t:       1
long int:      0
long long int: 1

However, in 64-bit GCC compiles, the output is different:

int:           0
int64_t:       1
long int:      1
long long int: 0

This is due to a difference in the definition of int64_t in 64-bit mode:

<code class="c++"># if __WORDSIZE == 64
typedef long int  int64_t;
# else
__extension__
typedef long long int  int64_t;
# endif</code>

In 64-bit mode, int64_t is defined as long int, not long long int.

To fix this, one could specialize the is_int64 template for long long int:

<code class="c++">#if defined(__GNUC__) && (__WORDSIZE == 64)
template <>
bool is_int64<long long int>() { return true; }
#endif</code>

However, this is a hackish solution. Is there a way to specify type equivalence to the compiler?

Unfortunately, it is not possible in C/C . The compiler defines basic data type equivalence, and typedefs only go one way.

An alternative workaround is to use type traits to check the properties of types, rather than relying on their exact names:

<code class="c++">template <typename T>
struct some_type_trait : boost::false_type { };

template <>
struct some_type_trait<int64_t> : boost::true_type { };

// Usage
if (some_type_trait<long int>::value) {
    // ...
}</code>

This approach allows for checking type properties without explicitly comparing types.

The above is the detailed content of Why does `long int` sometimes behave like `int64_t` in C ?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn