ホームページ >バックエンド開発 >C++ >64 ビット GCC コンパイルで「int64_t」の動作が異なるのはなぜですか?

64 ビット GCC コンパイルで「int64_t」の動作が異なるのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-10-30 19:19:311052ブラウズ

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

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 long int ではなく、long int として定義されます。これは、int64_t をチェックする is_int64() テンプレートの特殊化が、long long int ではなく、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 ビット整数型。

以上が64 ビット GCC コンパイルで「int64_t」の動作が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。