プロが教えるわが家の防犯対策術!

32bitマシンで使っていたソースを、64bit化する際に
気をつけたこと、困った経験などがありましたら、教えて下さい。

どういったことが問題になるのか、勘所がわからないので、
勉強の為に質問させていただきました。
具体例なんかあると嬉しいです。
よろしくお願いします。

A 回答 (5件)

#3です。


>tatsu99さんは、64bit対応の際に、まずそれぞれの型のバイト長を
>調べて、2.long型を使用しないとされたんでしょうか。
その通りです。プログラマたるもの、そのぐらいは常識です。
マニュアルで調べ、かつ全ての型を、
printf("charのサイズ=%d",sizeof(char));
printf("char*のサイズ=%d",sizeof(char*));
printf("intのサイズ=%d",sizeof(int));
のようにして調べて下さい。
その結果、long型が32ビットと64ビットで異なるため通常は使用しないようにしました。

>私はintを使わないようにと言われたことがあります。
>なぜなのかよくわかってないので、
int型は、かつての古きよき時代(MS-DOSの時代)には2バイトでした。そのため、int型は、OSによりサイズが異なると思っている人が多いです。そのために、上記のことをいわれたのかと思います。この認識は、正しい場合もあり、そうでない場合もあります。(HP-UX,solarisでは正しくありません)
どのOS(又はコンパイラ)で、64ビットにするかは、わかりませんが、それが、明確になったとき、全ての型のサイズを自分で調べることが、大切です。
    • good
    • 1
この回答へのお礼

重ね重ねアドバイスありがとうございます。
32bit, 64bitマシン・RedHatLinux(gcc)で表示させたところ、
以下のようになりました。

32bit環境:
char size = 1
short size = 2
int size = 4
long size = 4

64bit環境:
char size = 1
short size = 2
int size = 4
long size = 8

64bit環境ではlong型が8バイトになっています。
int型はCPUビット数の大きさなのかと思っていたのですが、
これは少なくとも現在のRedHatLinux(gcc)では成立しないのですね。
とするとTacosanさんにご指摘いただいた、int型は4バイト、という
勘違いをしてしまいそうです。

なんだか、型名っていったい何、、
プログラム書くときに、どれを使ったらいいの、、
などなど、また新たな迷宮の入り口に立ったような気がいたしますが(苦笑)
意識しながら勉強を続けていこうと思います。ありがとうございました。

お礼日時:2007/01/17 10:24

まあ, 重要なのは「この型なら大きさはこれだけ」という仮定をおかないってことでしょうか. もっとも, 規格を作る方も「全然仮定できないとどうにもならない」ってことは理解したらしく, 今の ANSI C では「そこそこの仮定」を許すためのヘッダとして stdint.h が用意されています.


ちなみに 64ビット化に関しては LP64, ILP64, LLP64 なんて表現があって
LP64: int = 32ビット, long = 64ビット
ILP64: int = long = 64ビット
LLP64: int = long = 32ビット, long long = 64ビット
だったような気がします. なので, 厳密には「long を使わなければ安全」でもない. もっというと sizeof(long long) = 1 かもしれないんですが, まあそんな環境は現れないと思いたい (苦笑).
で, #2 で言ってるのは「sizeof(int) = 4 を仮定するコード」(つまり sizeof(int) を使わずリテラルの 4 をそのまま使うコード) はしばしばあったりするんだけど同様に「sizeof(void*) = 4 を仮定する」あるいは「sizeof(void*) = sizeof(int) を仮定する」コードもある, って話. 今どきのコードではどうか知りませんが, ちょっと古いコードだと結果的にこのような仮定ができてしまって「コンパイルできね~」とか悩むことになったりします, というか実際悩みました.
    • good
    • 0
この回答へのお礼

size(long long)=1ですか、それはさすがにない…でしょうね(笑)
LP64,ILP64, LLP64は初めて聞いたキーワードだったので、
ぐぐって調べさせていただきました。ありがとうございます。
そして、以下のページに行き着きました。
誰かの役に立つかもしれないので、一応貼っておきます。
ご回答ありがとうございました。
http://www.itmedia.co.jp/enterprise/articles/050 …

お礼日時:2007/01/18 18:46

HPとsolarisで64ビット化を行った時の経験です。


int型は4バイトのままです。long型が32ビットと64ビットで異なります。
また、ポインターのsizeが異なります。
まとめると、以下のようになります。
       32ビット  64ビット
char      1バイト   1バイト
short     2バイト   2バイト
int      4バイト   4バイト
long     4バイト   8バイト
long long int 8バイト   8バイト
ポインター   4バイト   8バイト
32ビットへの移植を考慮した場合、以下の点がポイントになります。
1.ポインターのサイズを4バイトと決めつけない
2.long型を使用しない
3.8バイト整数は、longではなくlong long intを使う
4.OSから提供されるシステムコールのパラメータについては、
その型をそのまま使う。
size_t,time_t,pid_t等(これらは、最終的にはlong型にたどり着く可能性がありますので、int型で代用すると、痛い目に合います。)
size_t,time_t等は、32ビットか64ビットかにより、サイズが異なる可能性があります。(実際、solarisでは異なっていました)
従って、本来time_tを使うべきところで、intを使っていると64ビット化したとき、バグを誘発する可能性があります。

LINUX,windowsでの64ビット化は、やったことがないので、上記が当てはまるかどうかは、不明です。
上記の前提が、あてはまるとすれば、
32ビットのソースで、下記の点が、あるかどうかをチェックした方が良いでしょう。
1.ポインターを4バイトに決めつけているソースがないか。
2.time()の戻り値はtime_t型で受けるべきであるが、intで受けてないか等。一般的には、システムコールの本来の型で受けるべきものを、intで受けてないか。
    • good
    • 1
この回答へのお礼

long long intというのは知りませんでした。
tatsu99さんは、64bit対応の際に、まずそれぞれの型のバイト長を
調べて、2.long型を使用しないとされたんでしょうか。
私はintを使わないようにと言われたことがあります。
なぜなのかよくわかってないので、それも調べて勉強してみます。
ご回答ありがとうございました。

お礼日時:2007/01/17 00:37

sizeof(void*) = sizeof(int) = 4 を仮定してるコードが意外とあるので注意.

この回答への補足

もうちょっと考えました。
たとえばポインタを格納する配列を作るのに、
int* pContainer = (int *)malloc(4*1000);
なんてことをしているプログラムがあるってことでしょうか。
確かにありそうですね。

補足日時:2007/01/17 00:48
    • good
    • 0
この回答へのお礼

ええっと、むむ、私には理解できませんでした。。
sizeofを使っているのに、sizeof(int)=4と仮定するというのは、どういうことですか?

お礼日時:2007/01/17 00:31

I/Oを叩いているなどメモリのリソース管理をしている場合は今までなかった上位32ビットを0で埋めておかないと、32ビットアプリを64ビットOSで動かすと管理しきれなくなるというのが考えられます。



通常のアプリケーションをCライブラリを用いて64ビット用オプション付きで再コンパイルする分には(コンパイラの文法が改訂になった場合を除いて)あまり気にする部分は無いと思われます。

intの長さが32ビットから64ビットに変更になっている場合はキャストやシフト演算の互換性に注意がいるとおもわれます。
    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。
I/Oを叩くというのが、いまいちピンとこないのですが、メモリのリソース管理はアドレス値を扱っているので、32→64bit化するときには、その辺りの対応が必要ということでしょうか。
すいません、I/Oポートを操作したことがないので、具体的にイメージできていませんが。。

お礼日時:2007/01/17 00:22

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!