C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: arrayと構造体を同じ保存構造にしたい


(過去ログ 121 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■72540 / inTopicNo.1)  arrayと構造体を同じ保存構造にしたい
  
□投稿者/ すず (1回)-(2014/06/14(Sat) 15:17:58)

分類:[C/C++] 

例:
unsigned char ca[4]{ 1, 2, 3, 4};


typedef struct {

unsigned char w;
unsigned char x;
unsigned char y;
unsigned char z;

} Uchar4;

Uchar4 uc4;

確実に下記操作または関係を成立させるために、どんなコンパイルスイッチが必要でしょうか。

memcpy(&uc4, ca, sizeof(char)*4);

すると、

uc4.w == ca[0];
uc4.x == ca[1];
uc4.y == ca[2];
uc4.z == ca[3];

になります。


/////////もう一つの例//////////////////


float fa[4]={ 0.1, 0.2, 0.3, 0.4};

typedef struct {

float w;
float x;
float y;
float z;

} Float4;

Float4 f4;

確実に下記操作または関係を成立させるために、どんなコンパイルスイッチが必要でしょうか。

memcpy(&f4, fa, sizeof(float)*4);

すると
f4.w == fa[0];
f4.x == fa[1];
f4.y == fa[2];
f4.z == fa[3];

になります。



どうぞ宜しくお願いします。















引用返信 編集キー/
■72543 / inTopicNo.2)  Re[1]: arrayと構造体を同じ保存構造にしたい
□投稿者/ επιστημη (110回)-(2014/06/15(Sun) 00:22:16)
コンパイルスイッチ云々の話がしたいのであれば、コンパイラは何使うのかを示しておくれよ。

Visual C++ なら、ココ↓読んでおくれ。
http://msdn.microsoft.com/ja-jp/library/xh3e3fd0.aspx

引用返信 編集キー/
■72545 / inTopicNo.3)  Re[2]: arrayと構造体を同じ保存構造にしたい
□投稿者/ すず (2回)-(2014/06/16(Mon) 09:37:35)
επιστημη さん

お世話になります。
非常に良いページをご紹介下さって有難うございます。

ただ、下記の文に不思議感じます。
何で、このようなことをやるの?という感じですね。
==================================
構造体を 1 バイト境界上にパックします。 /Zp と同じ。
構造体を 2 バイト境界上にパックします。
構造体を 4 バイト境界上にパックします。
構造体を 8 バイト境界上にパックします (既定値)。
構造体を 16 バイト境界上にパックします。

==================================

これらの間に何が違うの?

何で「構造体を 8 バイト境界上にパックします」を "既定値"とされるの?
-----確かにこれで不都合発生した記憶はないですね。
そうしたら、その他の設定は何のためでしょうか。

初歩的な質問で、申し訳ありませんが。
----でも、もしかして、これこそ説明しにくいコンピューターの重大な原理かな。


どうぞ宜しくお願いします。














No72543 (επιστημη さん) に返信
> コンパイルスイッチ云々の話がしたいのであれば、コンパイラは何使うのかを示しておくれよ。
>
> Visual C++ なら、ココ↓読んでおくれ。
> http://msdn.microsoft.com/ja-jp/library/xh3e3fd0.aspx
>
引用返信 編集キー/
■72547 / inTopicNo.4)  Re[3]: arrayと構造体を同じ保存構造にしたい
□投稿者/ しま (75回)-(2014/06/16(Mon) 13:21:46)
No72545 (すず さん) に返信
> επιστημη さん
>
> お世話になります。
> 非常に良いページをご紹介下さって有難うございます。
>
> ただ、下記の文に不思議感じます。
> 何で、このようなことをやるの?という感じですね。
> ==================================
> 構造体を 1 バイト境界上にパックします。 /Zp と同じ。
> 構造体を 2 バイト境界上にパックします。
> 構造体を 4 バイト境界上にパックします。
> 構造体を 8 バイト境界上にパックします (既定値)。
> 構造体を 16 バイト境界上にパックします。
>
> ==================================
>
> これらの間に何が違うの?
>
> 何で「構造体を 8 バイト境界上にパックします」を "既定値"とされるの?
> -----確かにこれで不都合発生した記憶はないですね。
> そうしたら、その他の設定は何のためでしょうか。
>

「xx バイト境界(バイトバウンダリー)上にパックします」の意味が分っていると考えていいですか?

> 初歩的な質問で、申し訳ありませんが。
何故、”初歩的”な質問だとお分かりなのでしょう??

> ----でも、もしかして、これこそ説明しにくいコンピューターの重大な原理かな。

コンピューター一般ではなく、x86 のようにバイト単位に番地があって、かつバイト単位のべき乗(2のn乗)の大きさ単位で
(BYTE(8), SHORT(16), LONG(32), int64(64), etc) メモリーアクセス可能なものにとっての特性によるものです
i386 以降の x86 にとっては 8バイト境界になっている時が(整数のデーターでは)一番メモリーアクセスにとって都合がいいのです。
それで、 8 バイト境界でパックするのを既定とするのです

引用返信 編集キー/
■72548 / inTopicNo.5)  Re[4]: arrayと構造体を同じ保存構造にしたい
□投稿者/ しま (76回)-(2014/06/16(Mon) 13:34:51)
No72547 (しま さん) に返信

> コンピューター一般ではなく、x86 のようにバイト単位に番地があって、かつバイト単位のべき乗(2のn乗)の大きさ単位で
> (BYTE(8), SHORT(16), LONG(32), int64(64), etc) メモリーアクセス可能なものにとっての特性によるものです
> i386 以降の x86 にとっては 8バイト境界になっている時が(整数のデーターでは)一番メモリーアクセスにとって都合がいいのです。
> それで、 8 バイト境界でパックするのを既定とするのです
>
正確には外部バスが 64bit なのは i386 ではなく Pentium 4 以降かもしれない
引用返信 編集キー/
■72549 / inTopicNo.6)  Re[5]: arrayと構造体を同じ保存構造にしたい
□投稿者/ みい (11回)-(2014/06/16(Mon) 14:46:20)
> これらの間に何が違うの?
http://www.g-ishihara.com/c_st_01.htm
上記の説明でわかりにくい場合は「構造体 アライメント」で検索してください。
引用返信 編集キー/
■72550 / inTopicNo.7)  Re[6]: arrayと構造体を同じ保存構造にしたい
□投稿者/ 774RR (164回)-(2014/06/16(Mon) 17:22:59)
Visual C++ の場合 alignment は「サイズの違う型が並ぶ場合」にのみ適用だ。
最初の例題の構造体の場合、同じ型が並んでいるわけで
-Zp オプションでは提示の構造体のパッキングは変化しない。指定しても無駄だ。

C++03 と C++11 とで POD の定義がごっそり変わっているので
JIS X 3014:2003 (言語規格書 C++) は省略。

JIS X 3010:2003 (言語規格書 C) をめくってみた
6.2.5 型
・配列型は、要素型<snip>の集合を連続して割り付けたものを表す
・構造体型は、メンバ<snip>の集合を順に割り付けたものを表す
6.7.2.1 構造体指定子及び共用体指定子
・構造体メンバの記憶域は並べられた順に割り付ける
・構造体のビットフィールド以外の各メンバの境界はその型に適した処理系定義の方法で調整する
・構造体の中に詰め物があってもよいが、先頭に詰め物があってはならない
・構造体の最後に詰め物があってもよい

ということで
・ w->x->y->z の順にアドレスが増加することは言語規格書が保証している
・ w が [0] と同じアドレスにあることは言語規格書が保証している
・ x が [1] と同じアドレスであるかどうかは言語規格書レベルでは定かでない

一方で詰め物規則は処理系定義なことから Microsoft の文書が必ずあるはずで、検索したら
http://msdn.microsoft.com/ja-jp/library/cc438758.aspx
http://msdn.microsoft.com/en-us/library/cc953fe1.aspx
だから、提示の struct で詰め物は発生しないこととなる。
「結果的に」特にコンパイルオプションを指定する必要も無く
提示の struct は配列とバイナリ配置互換になるはずだ (Visual C++ の場合)

現実的 CPU アーキテクチャ的には、この両者が非互換になる必然がある実装が思いつかないので
おそらくほかのコンパイラでも (gcc とかでも) コンパイルオプションなしでバイナリ互換になるはず。
# 保証はしない

かたっぽ配列、かたっぽ構造体で扱うってかっこ悪いので俺ならこういうコードは書かないだろう。
何か一工夫すればこういう(変換しない変換)っていらないはずだけど。

引用返信 編集キー/
■72551 / inTopicNo.8)  Re[3]: arrayと構造体を同じ保存構造にしたい
□投稿者/ yukihiro (1回)-(2014/06/16(Mon) 17:35:02)
ていうか、ご自分で

> 確実に下記操作または関係を成立させるために、

という要望を出しておきながら、

> 何で、このようなことをやるの?という感じですね。

> -----確かにこれで不都合発生した記憶はないですね。
> そうしたら、その他の設定は何のためでしょうか。

という疑問が出てくることが不思議に思いました。

>不都合発生
したから、
> 確実に下記操作または関係を成立させ
たい、と思ったのではないのでしょうか。

別に煽ったり揚げ足をとるつもりはありませんが、
その辺りを説明されるとよりよい回答が得られる気がします。

引用返信 編集キー/
■72556 / inTopicNo.9)  Re[4]: arrayと構造体を同じ保存構造にしたい
□投稿者/ すず (3回)-(2014/06/17(Tue) 10:58:30)

皆さん丁寧なご教授本当にありがとうございました。
技術の深さと皆さんの造詣の深さを同時に感じました。

自分がこれから倍努力しなければならないと思います。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -