トップページ > プログラム > 2014年06月05日 > a9B4CiIQ

書き込み順位&時間帯一覧

27 位/289 ID中時間01234567891011121314151617181920212223Total
書き込み数1200000000000000000000014



使用した名前一覧書き込んだスレッド一覧
デフォルトの名無しさん
453
くだすれFORTRAN(超初心者用)その6

書き込みレス一覧

くだすれ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とかベクトル化の単位に合わせている
可能性が高いと思う。


※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。