• ベストアンサー

32bitデータの取得マクロ関数

int data[2]; // 64bit分のグローバルデータ /* 関数マクロ */ GET_DATA(tmp) \ do{\ /* int test = 0; */ memcpy(&tmp, &data[1] , 32) \ while(0) 質問は2つあります。 (1)64bitのデータから下位32bit分のデータの取得用の関数 マクロを教えてください。エンディアンはビッグエンディアンです 上記のように、マクロ関数に引数を渡して、データをコピーすることは可能ですか? (2)基本的な質問ですが、マクロ関数内で変数定義は可能ですか? よろしくお願いします。

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

  • ベストアンサー
noname#208507
noname#208507
回答No.3

間違っていたらすみません。もしかすると質問は、ビッグエンディアンの64bitデータから下位32bit分のデータをリトルエンディアンに変換したいという意味でしょうか。つまりこの場合、プログラムを実行するのはリトルエンディアン環境ではないでしょうか? もうしそうだとすると tmp = data[1]; では正しいデータは得られません。memcpyでも同様です。32bitごとだけでなく、16bitごと、8bitごとも上位・下位の交換が必要になります。 (32bit OSだとすれば)次のように書いて #ifdef _WIN32 # include <stdlib.h> # define GET_DATA(val) _byteswap_ulong((val)) #else # include <arpa/inet.h> # define GET_DATA(val) ntohl((val)) #endif 次のように使えばよいでしょう。 tmp = GET_DATA(data[1]); データ型に注意してください。

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

「マクロ関数」ではありません。「関数(形式)マクロ」です。 マクロはあくまで、文字列の置き換えしかしません。 Cコンパイラは、マクロが展開された後のソースコードをコンパイルします。 「変数定義は可能ですか?」等、全ての判断は「展開されたソースコード」が「正しいCのプログラムになっているか?」になります。 例えば #define FOO(a) int i=3*a ;printf("%d\n",i) と定義したとして int main(){ FOO(5); return 0; } これは正しいですが int main(){ FOO(5); FOO(8); return 0; } これは間違いです。 ところで、どんな環境向けで、どんなコンパイラを使っているのでしょう? C99準拠などで、64bit整数型があるコンパイラなら、それを使って、シフト演算と&で計算するのが楽ですし、保守性も移植性も高いです。 あと、memcpy使う意味は? 4byte程度の転送なら、どのコンパイラでも、memcpyよりtmp = data[1] ;の方が効率的で高速なアセンブリコードになると思いますよ。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

(1) memcpyの第3引数はビットサイズじゃありませんから、あっさりバッファオーバーフローしますね。 つーかその定義なら、普通に tmp = data[1]; でいいんじゃないですか。 #なおsizeof(int)=4とは限りません。 (2) もちろんできますが、逆に何を心配してるのでしょうか。