• ベストアンサー

型のバイト数はビルド時に全部決まりますか?

めちゃめちゃ根本的なことなのですがw (C++で)全ての型のバイト数は必ずビルド時(もっというとコンパイル時)に決定されるのでしょうか? (つまり、何バイトの整数型、何バイトの浮動小数型、とかいった分類でしかなくなるために、どのOSでも結果的にその部分は互換性が保たれる、ということなのでしょうか?) それとも、たとえばintが2バイトでも4バイトでも動作するように、コンパイル時には型情報(?)みたいなものが出来るだけで、実際のバイト数は実行時に計算されるのでしょうか? クラスや構造体がアラインメントに沿うように詰め物をされることとか、sizeofがtemplate内であれこれ使われてる状況を考えると、おそらく必ず前者ではないかと思うのですが…

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

> ポインタのバイト数は32ビットだと4バイトで、完璧に64ビット用だと8バイトになって、16ビット用だと2種類はありますよね? C++の1バイトは8ビットとはかぎりませんので、32ビットでも4バイトになるかどうかは処理系によります。 いわゆる16ビットプロセッサの場合でも、アドレスは16ビット、20ビット、24ビットなどがあります。詰物ビットの存在を考えると、ポインタが32ビットになる可能性も十分あるでしょう。 また、関数へのポインタとオブジェクトへのポインタでサイズが異なるとか、オブジェクトへのポインタであっても型によってサイズが異なるといったこともあり得ます。 > それらは様々なところで別々に配布されてる現状をみると > それぞれ用に(場合によっては別のコンパイラで)コンパイルしないとダメ、と考えていいのでしょうか? どこまでの範囲を想定しているのかわかりませんが、ターゲットが異なれば互換性がないと考えるべきです。

LongSecret
質問者

お礼

ありがとうございます。 確かに言われてみればその通りですね。 とりあえず >どこまでの範囲を想定しているのかわかりませんが、ターゲットが異なれば互換性がないと考えるべきです。 最も知りたかったことはここなので、助かります。 ただ、他の部分はなるほどと思いましたが >オブジェクトへのポインタであっても型によってサイズが異なるといったこと この部分は知りませんでした。 具体的にはどのようなケースが存在するのでしょうか?

その他の回答 (4)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

> そのケースは、現在普及しているものの総量からいうと、大よそどれくらいの割合になるのでしょうか? 限りなくゼロに近いと思います。 しかし、実際に自分が相手にしなければならない処理系がそのようなものであった場合、世間一般での普及状況がどうであるかは何ら関係ありません。 ですので、特定のひとつまたはいくつかの処理系のことだけを想定しているのであれば、それを明示して質問されたほうがよいと思います。 そうでなければ、遭遇頻度がどんなに低くても、存在する可能性がある以上、同列に扱わなければなりません。

LongSecret
質問者

お礼

>しかし、実際に自分が相手にしなければならない処理系がそのようなものであった場合、世間一般での普及状況がどうであるかは何ら関係ありません。 おっしゃる通りですね♪ まぁ、私はまだ大筋のプログラムが完成して、「よっしゃ~、じゃ他の稀なケース用にも用意しておくか」という段階にはいっておらず、とりあえずは先にWindowsを中心に(それも、古いOSだとサポートが既にないとか、使い方によってはメモリ的に厳しいのではないかとかいうこともあるので、本当のことを言うとXP以降あたりから推奨というぐらいに、とりあえず限定です)してプログラミングしていって、その中でもだいたい大抵の場合はこれで大丈夫、大よそ完成といえる段階までいったら 他のOS用にまた別途コンパイルも考えたくなることが予想される (その時の対象までは細かく考えていませんが、それでも全体からみれば全体の7~9割程度の環境で動けばいいというくらいです) ので、とりあえずは必要ないかもしれないけど、一応その時に楽に対応できればと思うので、念には念をということで色々と突っ込んだところを質問させていただいていますが 今回の件についてはおそらく十分な情報が得られましたので、これで締めとさせていただきます。 重ねて、どうもありがとうございます。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

> >オブジェクトへのポインタであっても型によってサイズが異なるといったこと > この部分は知りませんでした。 > 具体的にはどのようなケースが存在するのでしょうか? 例えば、プロセッサのアーキテクチャでは、アドレスが16ビットのワード単位で割り付けられているけれども、Cコンパイラとしては1バイトを8ビットにしたいような状況を考えてみてください。 short型以上は、プロセッサのアドレスをそのままポインタの値にできますが、char型の場合は、プロセッサのアドレス値に加えて、上位か下位かをしているする情報が必要になります。結果として、char型へのポインタが他の型へのポインタより大きくなる可能性があります。

LongSecret
質問者

お礼

なるほど、確かにそうですね。 そのケースは、現在普及しているものの総量からいうと、大よそどれくらいの割合になるのでしょうか? またその場合でも、コンパイルしてしまった後なら、それぞれの型のポインタにsizeofとしてやったときに、必ず一定の値が得られる、ということで大丈夫ですか?

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

C99では、可変長サイズの配列を使うことができます。 例えば、 int n ; scanf("%d", &n); int array[n]; のように、実行時でなければ要素数を決定できない配列があります。 この場合、型のバイト数というか、オブジェクトの型およびバイト数は実行時でなければ決定できません。 これはC99であってC++ではないのですが、C++であってもC99と同様の可変長配列を独自拡張としてサポートしている処理系もあります。 その場合は、C++であっても、オブジェクトの型およびサイズは実行時でなければ決定されません。 「型のサイズ」という意味では微妙ではありますが...

LongSecret
質問者

お礼

へぇ、C99ではそれがありなんですか。 ありがとうございます♪ あの後一番気になったことがあるのですが ポインタのバイト数は32ビットだと4バイトで、完璧に64ビット用だと8バイトになって、16ビット用だと2種類はありますよね? それらは様々なところで別々に配布されてる現状をみると それぞれ用に(場合によっては別のコンパイラで)コンパイルしないとダメ、と考えていいのでしょうか?

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.1

ご想像どうり前者となります (使っているコンパイラに依存します)

LongSecret
質問者

お礼

ありがとうございます♪ ということは、実際の動作を考えたときに 単純に 32ビットPCでは8バイトの変数があったら 2回で読み 16ビットのCPUでは 4回で読む という動作になるだけ、ということで大丈夫でしょうか?

関連するQ&A