web-dev-qa-db-ja.com

long intのサイズは常に4バイトであると想定できますか?

long int(私の知る限り、longの同義語です)は4バイト?

それに頼ることができますか?そうでない場合、POSIXベースのOSに当てはまるでしょうか?

70
Elimination

規格では、char以外の整数型の正確なサイズについては何も述べていません。通常、longは、32ビットシステムでは32ビット、64ビットシステムでは64ビットです。

ただし、標準ではminimumサイズが指定されています。 C Standard のセクション5.2.4.2.1から:

1以下に示す値は、#if前処理指令での使用に適した定数式に置き換えられます。さらに、CHAR_BITおよびMB_LEN_MAXを除き、以下は、整数プロモーションに従って変換された対応するタイプのオブジェクトである式と同じタイプの式に置き換えられます。 それらの実装定義の値は、示されているものと同じ大きさ(絶対値)以上であり、同じ符号であるものとする

...

  • タイプlong intのオブジェクトの最小値

    LONG_MIN -2147483647 //-(2 ^ 31-1)

  • タイプlong intのオブジェクトの最大値

    LONG_MAX +2147483647 // 2 ^ 31-1

これは、long intmustが最低32ビットである必要があるが、それより大きくなる可能性があることを示しています。 CHAR_BITが8のマシンでは、これにより4の最小バイトサイズが得られます。 CHAR_BITは16に等しく、long intは2バイト長です。

これが実際の例です。次のコードの場合:

#include <stdio.h>

int main ()
{
    printf("sizeof(long) = %zu\n", sizeof(long));
    return 0;
}

Debian 7 i686での出力:

sizeof(long)= 4

CentOS 7 x64での出力:

sizeof(long)= 8

そのため、サイズについての仮定を行うことはできません。特定のサイズの型が必要な場合は、stdint.hで定義されている型を使用できます。次のタイプを定義します。

  • int8_t:符号付き8ビット
  • uint8_t:符号なし8ビット
  • int16_t:16ビットに署名
  • uint16_t:符号なし16ビット
  • int32_t:32ビットに署名
  • uint32_t:符号なし32ビット
  • int64_t:署名された64ビット
  • uint64_t:符号なし64ビット

stdint.hヘッダーは標準のセクション7.20で説明されており、正確な幅のタイプはセクション7.20.1.1で説明されています。標準では、これらのtypedefはオプションですが、ほとんどの実装に存在します。

106
dbush

いいえ、C標準もPOSIXもこれを保証しておらず、実際に ほとんどのUnixライクな64ビットプラットフォーム は64ビット(8バイト)longを持っています。

38
user395760

コードsizeof(long int)を使用して、サイズを確認します。現在作業しているシステムのlong intのサイズをバイト単位で示します。特にあなたの質問の答えはノーです。 C、POSIX、またはどこでも保証されていません。

20
Kevin Pandya

@delnanが指摘したように、POSIX実装はlongintのサイズを未指定のままにしており、32ビットシステムと64ビットシステムで異なることがよくあります。

longの長さは、ほとんどの場合ハードウェア関連です(多くの場合、CPU上のデータレジスタのサイズに一致し、OSデザインやABIインターフェースなどのソフトウェア関連の問題もあります)。

あなたの心を楽にするために、sizeofは関数ではなく、コンパイラ指令*です。したがって、コードはsizeofを使用するときに操作を使用しません-それは数字を書くことと同じです。ポータブル。

つかいます:

sizeof(long int)

* Daveがコメントで指摘したように、可変長配列を使用する場合など、コンパイル中に値を計算できない場合、実行時にsizeofが計算されます。

また、別のコメントで指摘されているように、sizeofは実装で使用されるパディングとアライメントを考慮します。つまり、使用中の実際のバイトはメモリのサイズとは異なる場合があります)。

特定のバイトサイズの変数を探している場合は、バイト配列または(サポートされていると思われる)stdint.h-@dbushが示唆するとおり。

14
Myst

ICLシリーズ39ハードウェアに最初にCを実装したときに、Wordで標準を採用し、データ型をshort = 32ビット、intであるそのマシンアーキテクチャの自然な表現にマッピングしました。 = 64ビット、long = 128ビット。

しかし、本格的なCアプリケーションは機能しないことがわかりました。それらはすべて、マッピングshort = 16、int = 32、long = 64を想定しており、それをサポートするようにコンパイラを変更する必要がありました。

公式の標準が何と言っても、長年にわたって誰もがlong = 64ビットに収束しており、変更される可能性はほとんどありません。

13
Michael Kay

標準long intのサイズについて何も示していないため、使用している環境に依存します。

環境のlong intのサイズを取得するには、sizeof演算子を使用してlong intのサイズを取得できます。何かのようなもの

sizeof(long int)

C標準では、型のサイズについて次の点のみが必要です。

  • int> = 16ビット、
  • long> = 32ビット、
  • long long(C99以降)> = 64ビット
  • sizeof(char)<= sizeof(short)<= sizeof(int)<= sizeof(long)<= sizeof(long long)
  • sizeof(char)== 1
  • CHAR_BIT> = 8

残りは実装が定義されているため、intが18/24/36/60ビット、補数の符号付き形式、sizeof(char)== sizeof(short)== sizeof(int)==を持つシステムに遭遇しても驚くことではありませんsizeof(long)== 4、標準の委員会が気にするエキゾチックなアーキテクチャのような48ビットの長さまたは9ビットの文字とC標準でサポートされるプラットフォームのリスト

上記のlong intに関するポイントは完全に間違っています。ほとんどのLinux/Unix実装はlongを64ビットタイプとして定義しますが、Windowsでは異なるデータモデルを使用するため、32ビットのみです(こちらの表をご覧ください 64ビットコンピューティング )。 32ビットまたは64ビットのOSバージョンに関係なく。

ソース

10
Rahul Tripathi

コンパイラーは、ハードウェアとOSのタイプに基づいてサイズを決定します。

そのため、サイズに関して仮定するべきではありません。

8

srmiscのブログ: から

標準では完全にコンパイラーに委ねられているため、同じコンパイラーがオプションやターゲットアーキテクチャに依存することもあります。

できません。

ちなみにlong intlongと同じです。

1
simhumileco

短い答え:いいえ! _long int_のサイズを固定した仮定を立てることはできません。なぜなら、標準(C標準またはPOSIX)は_long int_のサイズを文書化していないからです(繰り返し強調されるように)。あなたの信念に反例を提供するために、64ビットシステムのほとんどはサイズが64のlongを持っています!移植性を最大化するには、sizeofを適切に使用します。

sizeof(long int)を使用してサイズを確認し、longのサイズをバイト単位で返します。値はシステムまたは環境に依存します。つまり、コンパイラはハードウェアとOSに基づいてサイズを決定します。

0
Ehsan