Maison >développement back-end >C++ >Pourquoi `long int` se comporte-t-il parfois comme `int64_t` en C ?

Pourquoi `long int` se comporte-t-il parfois comme `int64_t` en C ?

Barbara Streisand
Barbara Streisandoriginal
2024-10-30 22:45:18512parcourir

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

Long Long Int vs. Long Int vs. Int64_t en C

Lors de l'utilisation de traits de type C, certains comportements particuliers peuvent être rencontrés. Considérons le programme suivant :

<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>

Dans les compilations 32 bits, le résultat est comme prévu :

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

Cependant, dans les compilations GCC 64 bits, le résultat est différent :

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

Cela est dû à une différence dans la définition de int64_t en mode 64 bits :

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

En mode 64 bits, int64_t est défini comme long int, pas long long int.

Pour résoudre ce problème, on pourrait spécialiser le modèle is_int64 pour long long int :

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

Cependant, il s'agit d'une solution hackish. Existe-t-il un moyen de spécifier l'équivalence de type au compilateur ?

Malheureusement, ce n'est pas possible en C/C . Le compilateur définit l'équivalence de base des types de données, et les typedefs ne vont que dans un sens.

Une autre solution de contournement consiste à utiliser des traits de type pour vérifier les propriétés des types, plutôt que de se fier à leurs noms exacts :

<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>

Cette approche permet de vérifier les propriétés des types sans comparer explicitement les types.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn