C 中的Long Long Int 與Long Int 與Int64_t
C 類型特徵可能會表現出古怪的行為,特別是在有符號64 位元的情況下整數類型。以下是原因的探討:
在32 位元和64 位元編譯(GCC 和MSVC)中,以下程式的行為符合預期:
<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>
輸出正確顯示int64_t 、long int和long long int 都是等效的64 位元整數型別。
但是,64 位元GCC 編譯會產生不同的結果:
int: 0 int64_t: 1 long int: 1 long long int: 0
這種令人驚訝的行為源自於int64_t 的C 標準函式庫定義:
<code class="cpp"># if __WORDSIZE == 64 typedef long int int64_t; # else __extension__ typedef long long int int64_t; # endif</code>
在64 位元編譯中,int64_t 被定義為long int,而不是long long int。這意味著檢查 int64_t 的 is_int64() 模板特化將匹配 long int 而不是 long long int。
使用部分模板特化的解決方案:
解決此問題問題,您可以使用部分模板專門化為long long int 明確定義is_int64():
<code class="cpp">#if defined(__GNUC__) && (__WORDSIZE == 64) template <> bool is_int64<long long int>() { return true; } #endif</code>
但是,此解決方案依賴編譯器,而對於每種受影響的類型實作可能很繁瑣。
使用Boost 的替代解決方案:
Boost 使用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>
此方法將正確識別所有等效的64 位元整數類型,無論它們在標準庫中的確切表示形式如何。
以上是為什麼 `int64_t` 在 64 位元 GCC 編譯中表現不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!