- くだすれFORTRAN(超初心者用)その6
452 :デフォルトの名無しさん[sage]:2014/06/05(木) 00:38:07.03 ID:a9B4CiIQ - >>451のいう通り、同じプログラム単位に書かれたら、後ろに追加になる。
COMMONはグローバル変数とは違う。メモリー領域の共有。 COMMON/mat/a(20)とCOMMON/mat/a1,a2,....,a25が別々のプログラム単位に あらわれたら、それはa(1)とa1の番地が等しくて、メモリー領域を共有している。 (ポインター風にいえば同じ番地を差している。)同様にa(2)はa2、a(3)はa3... a(20)はa20とメモリー領域を共有している。 さてa21に対応する配列要素はないのだが、メモリー上では配列をはみ出した a(21)にあたる番地を差すことになる。(配列はメモリー上で連続に確保される。 COMMON変数は、普通は、宣言順に詰めてメモリー上に配置される) だから、コンパイラが気を利かせて、名前付きCOMMONであっても、 最大サイズのCOMMONブロックの大きさを確保してくれていれば、 なんら問題は生じない。しかし、昔のHITACとか気の利かない堅物は、 最初に出会ったCOMMONブロックの大きさで領域確保するので、ちとまずい。 (ACOS>FACOM>HITACの順でけつの穴が小さい。) COMMONブロックの大きさが違っていいのは、名前付きCOMMONのみ。 今の質問者の場合はmatという名前がついているので、本来はサイズが違う のは許されていない。が、昔はよく使われていた。 だから別に驚くことでも何でもない。 ちなみに無名COMMONとは(COMMON //a(20) とか COMMON a(20)とか)
| - くだすれFORTRAN(超初心者用)その6
453 :デフォルトの名無しさん[sage]:2014/06/05(木) 01:27:46.66 ID:a9B4CiIQ - コンパイラのオプションでMAPファイルを書かせれば確かめられる。
Intel Fortranの場合、/MAPでいく。gfortran はちょっと見た感じ見つからんw 昔のコンパイラなら必ずあった。 MAPファイル内を探すと 0004:00000aa0 _MAT 00406aa0 <common> 0004:00000b20 ___native_startup_state 00406b20 <common> 0004:00000b24 ___native_startup_lock 00406b24 <common> 0004:00000b28 ___onexitend 00406b28 <common> 0004:00000b2c ___onexitbegin 00406b2c <common> 0004:00000b30 __NoHeapEnableTerminationOnCorruption 00406b30 <common> 0004:00000b34 ___dyn_tls_init_callback 00406b34 <common> こんな感じの出力がある。 ここで実験した感じでは、単精度4バイト*8個=32バイトづつ、 領域を確保していっている。COMMONでa1..a25 の場合、本来は4*25バイト あれば十分だが、8の倍数ごと確保しているようなので、 番地 00406aa0 から 00406b20 まで4*32バイト確保している。 COMMMONの現れる順番に関わらず、最大のサイズをとってくれている模様。 Intel子は気が利くなw 心ぴょんぴょん待ち〜
| - くだすれFORTRAN(超初心者用)その6
454 :453[sage]:2014/06/05(木) 01:28:36.28 ID:a9B4CiIQ - テストプログラム
subroutine sub() common/mat/a(20) a = 1.0 print *, a end program Console1 real a common/mat/a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,& a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,& a21,a22,a23,a24,a25 a = 0.0 print *, (Z'b20'-Z'aa0') / 4 end program Console1
| - くだすれFORTRAN(超初心者用)その6
458 :453[sage]:2014/06/05(木) 23:04:15.60 ID:a9B4CiIQ - >>456
虚心に読めよw 1.名前付きCOMMONで長さがそろわないのは文法違反。 2.ゆえにそれがどう扱われるかは、処理系依存。 3.したがって、自分の利用しているコンパイラがどう扱っているか調べる必要あり。 4.調べる方法の一例はMAPファイルを書かせること。実例をIntelCompilerで示した。 結論:そなたの使っているコンパイラがわからなければここでは答えようがない。 大抵の処理系では適当に慮ってやってくれるが、昔のHITACのような凡例も あるので何とも言えない。NAGとか文法にうるさいのを売りにしている処理系では 期待薄。 >>457 うむ。DECのαとか、64bit時代になってから、COMMON文の中までPaddingして メモリー・アラインメントをそろえてくるので、昔のプログラムを動かそうとすると やっかい。 Intelが32バイトづつ増やしているのは、AVXとかベクトル化の単位に合わせている 可能性が高いと思う。
|
|