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
Libérer: 2024-10-30 22:45:18
original
514 Les gens l'ont consulté

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>
Copier après la connexion

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

int:           0
int64_t:       1
long int:      0
long long int: 1
Copier après la connexion

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
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal