回答編集履歴

1

いくつか言い回しを修正

2022/03/11 13:36

投稿

rubato6809
rubato6809

スコア1380

test CHANGED
@@ -1,5 +1,5 @@
1
- 関数に構造体(構造体変数)を渡すことはできますので、printf() に構造体を渡すこともできます
1
+ 関数に構造体(構造体変数)を引数で渡すことはできので、printf() に構造体を渡すこともできなくないでしょう
2
- でも、構造体を渡せば全てのメンバ変数を出力する、という仕様はありません。
2
+ でも、構造体を渡せば全てのメンバ変数を出力する、という仕様は printf() にありません。
3
3
 
4
4
  私の説明に必要な部分を簡略化したコードで示します。
5
5
  ```C
@@ -34,20 +34,20 @@
34
34
  11, 3.141500
35
35
  sizeof animal = 16
36
36
  ```
37
- と、正しく(?)表示されました。質問者のコンパイラも64bit版だと思います。
37
+ と、正しく(?)表示されました。なので質問者のコンパイラも64bit版だと思います。
38
38
 
39
39
  構造体 animal のサイズも表示させました。どちらも16です。
40
- 普通sizeof int は4,sizeof doubleは8で合計12と思いきや、16です。
40
+ 普通 sizeof int は4,sizeof doubleは8で合計12と思いきや、16です。
41
41
  メンバ変数 eye と weight の間に4バイトの隙間があるのです。
42
42
 
43
- さて、関数に構造体を渡そうとすれば、**引数の領域**に構造体分(この場合は16バイト)のメモリが割当てられ、そこに animal の値代入 printf()に渡されます。
43
+ さて、関数に構造体を渡そうとすれば、**引数の領域**に構造体分(この場合は16バイト)のメモリが割当てられ、そこに animal の値代入し、そが関数=この場合は printf()に渡ます。
44
44
 
45
45
  しかし printf() は animal 構造体の定義を知りませんから、隙間があることも知りません。"%d, %f\n" という文字列(変換指定)に従って、引数領域を表示するだけです。
46
46
 
47
- その結果、32bit版では隙間部分を %f で表示しようとし全く違う値が表示されたのです。こういう事を、巷ではコンパイラの未定義動作とか実装依存とか呼んでるようです。ある環境でうまくいったからいっ他所でうまくいく保証無い事があるだからやっちゃいけないことなんです。
47
+ その結果、32bit版では隙間部分を %f で表示するこになってまい全く違う値が表示されたのです。こういう事を、巷ではコンパイラの未定義動作とか実装依存とか呼んでるようです。ある環境でうまくいったと他所でうまくいく保証無い事なので、やっちゃいけないことなんです。
48
48
 
49
49
  では64bitコンパイラでうまくいったのはなぜか。
50
- 32bitコンパイラと64bitコンパイラでは引数領域に違いがあるのです。それが**たまたま上手くいった**ように見えた理由す。その違いを具体的に説明するのは、面倒なのでパスしたい。
50
+ 32bitコンパイラと64bitコンパイラでは引数領域の構造に違いがあるのです。それが**たまたま上手くいった**理由と関係しています。その違いを具体的に説明するのは、面倒なのでパスしたい。
51
51
 
52
52
  ご注意。隙間ができるかどうかもコンパイラ次第、隙間ができない場合もあります。
53
53