Heim >Backend-Entwicklung >C++ >Warum verhält sich „int64_t' bei 64-Bit-GCC-Kompilierungen anders?
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!