📌 このページの使い方
各落とし穴は独立しています。作業中に発生した問題の症状から該当する項目を探して参照してください。
最適化によるコード境界の消失
コンパイラの最適化(インライン展開・デッドコード除去)によって、元のソースに存在していた段落名やサブルーチンがバイナリから消えることがあります。特に最適化レベルが高い(-O2 以上)場合に発生します。
再コンパイル時は最適化を無効化(-O0)してシンボルを保持するようにしてください。元のモジュールが最適化ビルドの場合、シンボルが完全に一致しないことは許容し、入出力比較テストで等価性を確認することに注力してください。
EBCDIC・文字コード・行末コードの罠
メインフレーム(z/OS)のテキストファイルは EBCDIC エンコーディングを使用しています。FTP や SCP でファイルを転送する際に ASCII/UTF-8 への変換が正しく行われないと文字化けします。また、COBOL ソースは固定長80桁形式(カラム1-72がコード、73-80はシーケンス番号)が前提の場合があります。
# iconv で EBCDIC → UTF-8 変換(IBM037 は EBCDIC US)
iconv -f IBM037 -t UTF-8 source.cbl > source_utf8.cbl
# 行末コードを CRLF → LF に変換
sed -i 's/\r//' source_utf8.cbl
# FTP での転送時はテキストモードを明示する
ftp -n mf-host <<EOF
user userid password
ascii
get 'HLQ.SRC.COBOL(MYPROG)' myprog.cbl
quit
EOF
コンパイラ方言(IBM拡張など)への対応
IBM Enterprise COBOL には標準 COBOL にない拡張構文(EXEC SQL・EXEC CICS・SERVICE RELOAD・TITLE 文など)があります。これらは GnuCOBOL では認識されません。
IBM 拡張構文を含む行は *> でコメントアウトして動作確認を進め、必要であれば GnuCOBOL の同等機能(EXEC SQL なら esql プリプロセッサ)に置き換えます。ただし移植・置換作業は PART 09 のモダナイゼーション工程として別途計画してください。
# EXEC SQL / EXEC CICS の行を抽出
grep -in "EXEC\s\+\(SQL\|CICS\)" src/**/*.cbl
# IBM 固有の SERVICE RELOAD
grep -in "SERVICE\s\+RELOAD" src/**/*.cbl
# TITLE 文
grep -in "^\s*TITLE\b" src/**/*.cbl
コピーブック不足によるコンパイルエラー
COPY 文で参照しているコピーブックが -I で指定したライブラリパスに存在しない。
コンパイルリストの展開済みソースからコピーブックの内容を逆生成します。
# ソース中のCOPY参照を全件抽出
grep -riho "COPY\s\+['\"]\\?[A-Z0-9-]\+" src/ | grep -oE "[A-Z0-9-]{2,}$" | sort -u > required_copybooks.txt
# 実在するコピーブックを列挙
find copybook/ -type f | xargs -I{} basename {} .cpy | sort -u > existing_copybooks.txt
# 不足しているコピーブックを表示
comm -23 required_copybooks.txt existing_copybooks.txt
動的 CALL が見つからない
動的 CALL(CALL WS-PROG-NAME のように変数でプログラム名を指定)は静的解析で検出できません。実行時に環境変数 COB_LIBRARY_PATH で指定したディレクトリに対象モジュールが存在しない場合に発生します。
# 動的 CALL の変数名を抽出(静的CALL除外)
grep -iE "CALL\s+[A-Z][A-Z0-9-]*\b" src/**/*.cbl | grep -v "CALL\s*'"
# 実行時ライブラリパスの設定
export COB_LIBRARY_PATH=./lib:./sub
# 動的ロードで見つからないモジュールを COB_SET_TRACE で特定
COB_SET_TRACE=Y ./myprogram 2>&1 | grep "CALL\|not found"