Heim >Backend-Entwicklung >C++ >Warum verhält sich „int64_t' bei 64-Bit-GCC-Kompilierungen anders?

Warum verhält sich „int64_t' bei 64-Bit-GCC-Kompilierungen anders?

Susan Sarandon
Susan SarandonOriginal
2024-10-30 19:19:311050Durchsuche

Why Does `int64_t` Behave Differently in 64-bit GCC Compiles?

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

C-Typ-Merkmale können eigenartiges Verhalten zeigen, insbesondere bei vorzeichenbehafteten 64-Bit-Versionen Integer-Typen. Hier erfahren Sie, warum:

Bei 32-Bit- und 64-Bit-Kompilierungen (GCC und MSVC) verhält sich das folgende Programm wie erwartet:

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

Die Ausgabe zeigt korrekt an, dass int64_t , long int und long long int sind alle äquivalente 64-Bit-Ganzzahltypen.

Eine 64-Bit-GCC-Kompilierung führt jedoch zu einem anderen Ergebnis:

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

Dieses überraschende Verhalten ist darauf zurückzuführen die C-Standardbibliotheksdefinition von int64_t:

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

In einer 64-Bit-Kompilierung ist int64_t als long int und nicht als long long int definiert. Dies bedeutet, dass die Vorlagenspezialisierung is_int64(), die nach int64_t prüft, mit long int statt mit long long int übereinstimmt.

Lösung mit teilweiser Vorlagenspezialisierung:

Um dieses Problem zu beheben Problem: Sie können eine teilweise Vorlagenspezialisierung verwenden, um is_int64() explizit für long long int zu definieren:

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

Diese Lösung ist jedoch vom Compiler abhängig und kann für jeden betroffenen Typ mühsam zu implementieren sein.

Alternative Lösung mit Boost:

Boost bietet eine elegantere Lösung mit der variadic-Vorlage boost::is_same:

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

Dieser Ansatz führt zur korrekten Identifizierung alle äquivalenten 64-Bit-Ganzzahltypen, unabhängig von ihrer genauen Darstellung in der Standardbibliothek.

Das obige ist der detaillierte Inhalt vonWarum verhält sich „int64_t' bei 64-Bit-GCC-Kompilierungen anders?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn