【COBOL】INITIALIZE文完全ガイド|型別初期値・WITH FILLER・REPLACING・MOVE ZEROSとの違い・落とし穴

COBOL のINITIALIZE文は、データ項目やグループ項目を型に応じた初期値(数値は0、文字はスペース)に一括でリセットする命令です。単純に見えて、内部数値型(COMP-3・COMP)を含むグループへのMOVE ZEROSが引き起こすバグや、FILLERが初期化されない挙動など、知らないと痛い落とし穴がいくつかあります。

この記事では、INITIALIZE文の動作原理と構文オプションを基礎から整理し、REPLACING句の全データ型・WITH FILLER・MOVE ZEROSとの違い・OCCURS配列への適用・実践的な初期化パターンまで詳しく解説します。

この記事でわかること

  • INITIALIZE文のデフォルト動作(型別の初期値ルール)
  • REPLACING句で任意の値を設定する全データ型の書き方
  • WITH FILLER(FILLER項目も含めて初期化する)
  • MOVE ZEROS / MOVE SPACES との違いと危険なケース
  • FILLERの初期化・88レベル条件名・REDEFINESへの動作
  • OCCURS配列・グループ項目の初期化パターン
  • よくある落とし穴(内部数値型・FILLER・REDEFINES)
スポンサーリンク

INITIALIZE文とは

INITIALIZE文は、指定した項目をデータ型に応じた「デフォルト初期値」にリセットする命令です。グループ項目を指定すれば、配下のすべての基本項目を一括で初期化できます。

データ型 INITIALIZE後の値
英数字系(PIC X, PIC A, PIC G) SPACES(スペース)
数値系(PIC 9, COMP, COMP-3, COMP-5 など) ZEROS(ゼロ)
数値編集項目(PIC Z・*・+ など) ZEROS(ゼロ編集後の形式)
英数字編集項目(PIC X の B・/ 挿入) SPACES
FILLER項目 初期化されない(デフォルト)
88レベル条件名 対象外(設定値は変更されない)
基本動作の確認
WORKING-STORAGE SECTION.
01  WS-CUSTOMER.
    05  WS-CUST-CODE   PIC X(6).           *> 英数字 → スペースに
    05  WS-CUST-NAME   PIC X(20).          *> 英数字 → スペースに
    05  WS-BALANCE     PIC S9(7)V99.       *> 数値   → 0に
    05  WS-POINTS      PIC 9(5) COMP-3.    *> COMP-3  → 0に(正しく)
    05  FILLER         PIC X(3).           *> デフォルトでは初期化されない
    05  WS-STATUS-CODE PIC 9(1).
        88  STS-ACTIVE   VALUE 1.
        88  STS-INACTIVE VALUE 0.

PROCEDURE DIVISION.
    *> グループ項目を指定すると配下の基本項目をまとめて初期化
    INITIALIZE WS-CUSTOMER

    *> 結果:
    *>   WS-CUST-CODE  → '      '(6スペース)
    *>   WS-CUST-NAME  → '                    '(20スペース)
    *>   WS-BALANCE    → 0
    *>   WS-POINTS     → 0(COMP-3形式で正しく0になる)
    *>   FILLER        → 変化なし(初期化されない)
    *>   WS-STATUS-CODE → 0(88レベルの条件名は関係なし)

    DISPLAY 'コード: [' WS-CUST-CODE   ']'
    DISPLAY '残高:   '  WS-BALANCE
    DISPLAY '明細数: '  WS-POINTS.

基本構文と構成要素

INITIALIZE文の完全な構文
INITIALIZE 項目名1 [項目名2 ...]
    [WITH FILLER]
    [  ALL TO VALUE
     | ALL TO DEFAULT
     | REPLACING
         {ALPHABETIC           DATA BY 値または変数}
         {ALPHABETIC-EDITED    DATA BY 値または変数}
         {ALPHANUMERIC         DATA BY 値または変数}
         {ALPHANUMERIC-EDITED  DATA BY 値または変数}
         {NATIONAL             DATA BY 値または変数}
         {NATIONAL-EDITED      DATA BY 値または変数}
         {NUMERIC              DATA BY 値または変数}
         {NUMERIC-EDITED       DATA BY 値または変数}
         {DBCS                 DATA BY 値または変数}
    ]
    [THEN TO DEFAULT].
オプション 意味
項目名(必須) 1つ以上の基本項目またはグループ項目
WITH FILLER FILLER項目も含めて初期化する(デフォルトは対象外)
REPLACING 特定の型だけ任意の値で初期化する
ALL TO VALUE VALUE句で定義した初期値にリセットする(COBOL 2002以降)
ALL TO DEFAULT 型のデフォルト初期値(数値=0、文字=スペース)にリセットする
THEN TO DEFAULT REPLACING適用後、それ以外の型をデフォルト値に初期化する

REPLACING句の全データ型

REPLACING句を使うと、特定のデータ型の項目だけ任意の値で初期化できます。型名に対応するデータ型の項目だけが対象になり、それ以外は変化しません。

REPLACING句の全データ型を使った例
WORKING-STORAGE SECTION.
01  WS-MIXED-GROUP.
    05  WS-ALPHA-1     PIC A(10).              *> アルファベットのみ
    05  WS-ALPHANUM    PIC X(15).              *> 英数字
    05  WS-NUM-EDIT    PIC ZZZ,ZZ9.99.         *> 数値編集
    05  WS-ALPHA-EDIT  PIC X/X/X.              *> 英数字編集
    05  WS-NUM-PLAIN   PIC 9(5)V99.            *> 数値
    05  WS-NATIONAL    PIC N(10).              *> 各国語文字(NATIONAL)

PROCEDURE DIVISION.
    *> 各型ごとに異なる初期値を指定
    INITIALIZE WS-MIXED-GROUP
        REPLACING
            ALPHABETIC           DATA BY 'X'
            ALPHANUMERIC         DATA BY '*'
            ALPHANUMERIC-EDITED  DATA BY ' '
            NUMERIC              DATA BY 0
            NUMERIC-EDITED       DATA BY 0
            NATIONAL             DATA BY N' '

    *> 結果:
    *>   WS-ALPHA-1    → 'XXXXXXXXXX'(Aはアルファベット型)
    *>   WS-ALPHANUM   → '***************'
    *>   WS-NUM-EDIT   → 0(ゼロ編集表示)
    *>   WS-ALPHA-EDIT → ' / / '
    *>   WS-NUM-PLAIN  → 0
    *>   WS-NATIONAL   → N' '(ナショナル文字スペース)

REPLACING句で指定しなかった型の項目は変化しません。たとえばREPLACING NUMERIC DATA BY 99とだけ書いた場合、数値項目は99になりますが文字項目はそのままです。

数値項目だけ特定値に初期化する
WORKING-STORAGE SECTION.
01  WS-SUMMARY.
    05  WS-DEPT-NAME   PIC X(20).
    05  WS-SALES-CNT   PIC 9(5).
    05  WS-SALES-AMT   PIC 9(9)V99.
    05  WS-ERROR-CNT   PIC 9(3).
    05  WS-LAST-DATE   PIC X(8).

PROCEDURE DIVISION.
    *> 部門名と最終日付は保持したまま、集計値だけ0クリア
    INITIALIZE WS-SUMMARY
        REPLACING NUMERIC DATA BY 0

    *> WS-DEPT-NAME と WS-LAST-DATE は変化しない
    *> WS-SALES-CNT、WS-SALES-AMT、WS-ERROR-CNT のみ 0 になる

WITH FILLER(FILLER項目も初期化する)

デフォルトのINITIALIZEはFILLER項目を初期化しません。固定長ファイルの出力レコードなど、FILLER部分も確実にクリアしたい場合はWITH FILLERを指定します。

WITH FILLERの動作の違い
WORKING-STORAGE SECTION.
01  WS-OUTPUT-REC.
    05  WS-REC-TYPE    PIC X(1).
    05  WS-ITEM-CODE   PIC X(8).
    05  FILLER         PIC X(2).    *> 区切り用スペース
    05  WS-AMOUNT      PIC 9(9)V99.
    05  FILLER         PIC X(5).    *> 予備領域
    05  WS-DATE        PIC 9(8).
    05  FILLER         PIC X(10).   *> 末尾パディング

PROCEDURE DIVISION.
    *> NG: FILLERが初期化されず前回の値が残ることがある
    INITIALIZE WS-OUTPUT-REC

    *> OK: FILLERも含めてすべてクリアする
    INITIALIZE WS-OUTPUT-REC WITH FILLER

    *> WITH FILLERを使った場合:
    *>   FILLER(PIC X)→ スペースになる
    *>   データ項目は通常通り型に応じた値になる

固定長ファイルの出力レコードは WITH FILLER を使う
FDのレコード定義や出力バッファには、位置合わせや将来の拡張のためにFILLERが散在していることがよくあります。INITIALIZE … WITH FILLERで確実にゼロ/スペースクリアしてから値をセットする習慣にすると、前回ループの残存データが紛れ込むバグを防げます。

INITIALIZE vs MOVE ZEROS / MOVE SPACES

グループ項目の初期化方法として INITIALIZE 以外に MOVE ZEROS TO グループ項目MOVE SPACES TO グループ項目 もよく使われますが、内部数値型(COMP-3・COMP・COMP-5)を含むグループには危険です。

MOVE ZEROS TO グループ は COMP-3 を壊す
MOVE ZEROS TO グループ項目はグループ全体を英数字として扱い、全バイトにゾーン数字の「0」(IBM EBCDIC では X'F0')を書き込みます。COMP-3(パックドデシマル)はBCD形式で格納されるため、バイト単位で「0」を書き込んでも正しい「ゼロ」にはなりません。その後 COMP-3 フィールドを算術演算すると、DATA EXCEPTION(S0C7)などの実行時エラーが発生します。

MOVE ZEROS とINITIALIZEの動作の違い
WORKING-STORAGE SECTION.
01  WS-PAY-DATA.
    05  WS-EMP-CODE    PIC X(6).
    05  WS-SALARY      PIC S9(7)V99  COMP-3.   *> パックドデシマル
    05  WS-BONUS       PIC S9(5)V99  COMP-3.
    05  WS-TAX         PIC S9(5)V99  COMP-3.

PROCEDURE DIVISION.
    *> NG: COMP-3フィールドにゾーン数字の0を書き込んでしまう
    *>     WS-SALARYなどが壊れ、算術演算で実行時エラーの原因に
    MOVE ZEROS TO WS-PAY-DATA

    *> NG: 全バイトをスペース(X'40')で埋める
    *>     数値フィールドに不正なビットパターンが入る
    MOVE SPACES TO WS-PAY-DATA

    *> OK: 各フィールドを型に応じた正しいゼロ/スペースで初期化
    *>     COMP-3 には BCD 形式の 0 が設定される
    INITIALIZE WS-PAY-DATA
方法 動作 適切な使用場面
INITIALIZE 型に応じた正しい初期値(数値=0、文字=スペース) COMP-3・COMPを含むグループ全般
MOVE ZEROS TO グループ 全バイトにゾーン数字の’0’を書き込む PIC X・PIC 9のみのグループ(COMP-3がなければOK)
MOVE SPACES TO グループ 全バイトをスペースで埋める 文字項目のみのグループ
MOVE ZEROS TO 基本項目 個別の数値項目をゼロにする 個別の PIC 9・COMP・COMP-3項目のゼロ化
パフォーマンス考慮: 大量データのゼロクリア
WORKING-STORAGE SECTION.
*> PIC 9 と PIC X だけのグループ(COMP-3なし)
01  WS-SIMPLE-TABLE.
    05  WS-COUNTER    PIC 9(7)   OCCURS 1000 TIMES.

*> COMP-3 を含むグループ
01  WS-FINANCIAL-TABLE.
    05  WS-FIN-ENTRY  OCCURS 500 TIMES.
        10  WS-FIN-AMT  PIC S9(9)V99 COMP-3.
        10  WS-FIN-CNT  PIC 9(5).

PROCEDURE DIVISION.
    *> PIC 9 のみの大量データ: MOVE ZEROS が若干高速な場合がある
    MOVE ZEROS TO WS-SIMPLE-TABLE

    *> COMP-3 を含む場合: INITIALIZE 以外の選択肢はない
    INITIALIZE WS-FINANCIAL-TABLE

FILLER・88レベル・REDEFINESへの動作

FILLER項目

デフォルトではFILLERは初期化されません。WITH FILLERを指定した場合のみ、FILLERが英数字ならスペース、数値ならゼロに初期化されます。

88レベル条件名

88レベルはデータを保持しないため、INITIALIZEの直接の対象ではありません。88レベルの親(基本項目)がINITIALIZEされると、その値が変わります。条件名の真偽は親項目の値で決まるため、INITIALIZE後に88レベルの真偽が変わることがあります。

88レベルへの影響
WORKING-STORAGE SECTION.
01  WS-STATUS    PIC 9(1) VALUE 1.
    88  STS-ACTIVE   VALUE 1.
    88  STS-INACTIVE VALUE 0.

PROCEDURE DIVISION.
    DISPLAY STS-ACTIVE     *> TRUE(WS-STATUSが1なので)

    INITIALIZE WS-STATUS   *> WS-STATUSが 0 に初期化される

    DISPLAY STS-ACTIVE     *> FALSE(WS-STATUSが0に変わったため)
    DISPLAY STS-INACTIVE   *> TRUE

REDEFINES項目

REDEFINES句で再定義された項目をINITIALIZEすると、REDEFINES先(再定義側)の型で初期化されます。同じメモリ領域を元の定義で読むと、REDEFINESで設定した初期値が見えます。

REDEFINESとINITIALIZEの組み合わせ
WORKING-STORAGE SECTION.
01  WS-DATE-FULL   PIC 9(8).
01  WS-DATE-PARTS  REDEFINES WS-DATE-FULL.
    05  WS-YEAR    PIC 9(4).
    05  WS-MONTH   PIC 9(2).
    05  WS-DAY     PIC 9(2).

PROCEDURE DIVISION.
    MOVE 20261231 TO WS-DATE-FULL

    *> WS-DATE-FULLをINITIALIZE → 0になる
    INITIALIZE WS-DATE-FULL
    *>   WS-DATE-FULL  → 00000000
    *>   WS-YEAR  → 0000(REDEFINES経由で同じメモリ)
    *>   WS-MONTH → 00
    *>   WS-DAY   → 00

    *> WS-DATE-PARTSをINITIALIZE → 各従属項目が0になる
    MOVE 20261231 TO WS-DATE-FULL
    INITIALIZE WS-DATE-PARTS
    *>   WS-YEAR  → 0000
    *>   WS-MONTH → 00
    *>   WS-DAY   → 00
    *>   WS-DATE-FULL → 00000000(同じメモリが変化)

OCCURS配列の初期化

INITIALIZEはOCCURS配列を含むグループ項目にも適用できます。親グループを指定するとすべての配列要素が一括で初期化されます。

OCCURS配列全体の初期化
WORKING-STORAGE SECTION.
01  WS-DEPT-TABLE.
    05  WS-DEPT-ENTRY  OCCURS 10 TIMES.
        10  WS-DEPT-CODE   PIC X(4).
        10  WS-DEPT-SALES  PIC 9(9)V99  COMP-3.
        10  WS-DEPT-CNT    PIC 9(5).
        10  FILLER         PIC X(3).

01  WS-IDX    PIC 9(2).

PROCEDURE DIVISION.
    *> 全10要素をまとめて初期化(COMP-3も正しくゼロになる)
    INITIALIZE WS-DEPT-TABLE

    *> FILLERも初期化したい場合
    INITIALIZE WS-DEPT-TABLE WITH FILLER

    *> 特定の要素だけ初期化(インデックスで指定)
    INITIALIZE WS-DEPT-ENTRY(3)   *> 3番目の要素だけリセット

    *> ループで条件付き初期化
    PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 10
        IF WS-DEPT-CODE(WS-IDX) = SPACES
            INITIALIZE WS-DEPT-ENTRY(WS-IDX)
        END-IF
    END-PERFORM.
多次元配列の初期化
WORKING-STORAGE SECTION.
01  WS-MONTHLY-TBL.
    05  WS-MONTH-ROW   OCCURS 12 TIMES.
        10  WS-WEEK-SALES  PIC 9(9)V99  COMP-3
                            OCCURS 5 TIMES.   *> 月×週の2次元

PROCEDURE DIVISION.
    *> 全要素(12か月×5週=60要素)を一括初期化
    INITIALIZE WS-MONTHLY-TBL

ALL TO VALUE(VALUE句の初期値にリセット)

COBOL 2002以降(GnuCOBOLなどで対応)では、ALL TO VALUE句を使うと、VALUE句で定義した初期値にリセットできます。プログラム起動時の状態に戻したい場合に便利です。

ALL TO VALUE の使用例
WORKING-STORAGE SECTION.
01  WS-CONFIG.
    05  WS-MAX-RETRY   PIC 9(2)  VALUE 3.
    05  WS-TIMEOUT     PIC 9(4)  VALUE 30.
    05  WS-DEBUG-MODE  PIC X(1)  VALUE 'N'.
    05  WS-LOG-LEVEL   PIC X(1)  VALUE 'I'.

PROCEDURE DIVISION.
    *> 処理中に設定を変更
    MOVE 5     TO WS-MAX-RETRY
    MOVE 60    TO WS-TIMEOUT
    MOVE 'Y'   TO WS-DEBUG-MODE
    MOVE 'D'   TO WS-LOG-LEVEL

    *> 処理後: VALUE句で定義した初期値に戻す
    INITIALIZE WS-CONFIG ALL TO VALUE
    *>   WS-MAX-RETRY  → 3(VALUE 3 に戻る)
    *>   WS-TIMEOUT    → 30
    *>   WS-DEBUG-MODE → 'N'
    *>   WS-LOG-LEVEL  → 'I'

ALL TO VALUE と ALL TO DEFAULT の違い
ALL TO VALUEはVALUE句で定義した値に戻します(VALUE句がない項目はデフォルト値)。ALL TO DEFAULTはVALUE句の内容を無視して型のデフォルト値(数値=0、文字=スペース)にします。ランタイムのコンフィグリセットにはALL TO VALUE、集計作業域のクリアにはINITIALIZE(デフォルト)またはALL TO DEFAULTが向いています。

実践パターン

バッチループ内の作業域クリア

1件処理ごとに作業域をリセットするパターンです。前ループの残存データが混入するバグを防ぎます。

ループ内の作業域クリア
WORKING-STORAGE SECTION.
01  WS-WORK-AREA.
    05  WS-WORK-KEY    PIC X(10).
    05  WS-WORK-AMT    PIC S9(9)V99  COMP-3.
    05  WS-WORK-CNT    PIC 9(5).
    05  WS-WORK-STATUS PIC X(2).
    05  FILLER         PIC X(4).

PROCEDURE DIVISION.
    PERFORM UNTIL WS-EOF
        *> 作業域を毎回クリア(FILLERも含めてリセット)
        INITIALIZE WS-WORK-AREA WITH FILLER

        *> レコードの処理
        PERFORM PROCESS-RECORD

        READ INPUT-FILE
            AT END MOVE 'Y' TO WS-EOF-FLAG
        END-READ
    END-PERFORM.

出力レコードの組み立て前初期化

固定長ファイルへの出力前に、レコード全体をスペース/ゼロクリアしてから値をセットするパターンです。前のレコードの内容が混入する問題を確実に防ぎます。

出力レコードの初期化から書き出しまで
WORKING-STORAGE SECTION.
01  WS-OUT-RECORD.
    05  WS-OUT-TYPE     PIC X(1).
    05  WS-OUT-CODE     PIC X(8).
    05  WS-OUT-AMOUNT   PIC S9(9)V99  COMP-3.
    05  FILLER          PIC X(2).             *> 区切り
    05  WS-OUT-DATE     PIC 9(8).
    05  WS-OUT-STATUS   PIC X(2).
    05  FILLER          PIC X(20).            *> 予備領域

PROCEDURE DIVISION.
    PERFORM PROCESS-OUTPUT-RECORD VARYING WS-IDX FROM 1 BY 1
            UNTIL WS-IDX > WS-REC-COUNT.

PROCESS-OUTPUT-RECORD.
    *> まず全体をクリア(FILLERも含む)
    INITIALIZE WS-OUT-RECORD WITH FILLER

    *> 必要な項目だけセット
    MOVE '1'             TO WS-OUT-TYPE
    MOVE WS-SRC-CODE     TO WS-OUT-CODE
    MOVE WS-SRC-AMOUNT   TO WS-OUT-AMOUNT
    MOVE WS-TODAY        TO WS-OUT-DATE
    MOVE 'OK'            TO WS-OUT-STATUS

    WRITE OUTPUT-RECORD FROM WS-OUT-RECORD
    EXIT.

集計テーブルの処理前リセット

部門別・月別などの集計テーブルを処理開始時にまとめてゼロクリアするパターンです。

集計テーブルの初期化
WORKING-STORAGE SECTION.
01  WS-AGG-TABLE.
    05  WS-AGG-ENTRY   OCCURS 50 TIMES.
        10  WS-AGG-KEY    PIC X(6).
        10  WS-AGG-SALES  PIC S9(11)V99  COMP-3.
        10  WS-AGG-CNT    PIC 9(7).
        10  WS-AGG-MAX    PIC S9(9)V99   COMP-3.
        10  WS-AGG-MIN    PIC S9(9)V99   COMP-3.
        10  FILLER        PIC X(4).

01  WS-GRAND-TOTAL   PIC S9(13)V99 COMP-3.
01  WS-ERROR-CNT     PIC 9(5).

PROCEDURE DIVISION.
    *> 処理開始: テーブルと集計変数を一括初期化
    INITIALIZE WS-AGG-TABLE WITH FILLER
    INITIALIZE WS-GRAND-TOTAL WS-ERROR-CNT

    *> 処理メインループ
    PERFORM PROCESS-ALL-RECORDS

    *> 結果出力
    PERFORM OUTPUT-RESULT.

サブプログラムの作業域初期化

WORKING-STORAGEはCALLをまたいで値が保持されます。毎回新鮮な状態で処理を始めたいサブプログラムは、PROCEDURE DIVISIONの先頭でINITIALIZEします。

サブプログラムの処理開始時初期化
IDENTIFICATION DIVISION.
PROGRAM-ID. CALC-SUB.

DATA DIVISION.
WORKING-STORAGE SECTION.
01  WS-WORK.
    05  WS-TEMP-1    PIC S9(9)V99  COMP-3.
    05  WS-TEMP-2    PIC S9(9)V99  COMP-3.
    05  WS-WORK-CNT  PIC 9(5).
    05  WS-WORK-FLG  PIC X(1).

LINKAGE SECTION.
01  LK-INPUT    PIC S9(9)V99.
01  LK-RESULT   PIC S9(11)V99.

PROCEDURE DIVISION USING LK-INPUT LK-RESULT.
    *> 毎回のCALLで作業域を確実にリセット
    INITIALIZE WS-WORK

    *> 処理
    MOVE LK-INPUT   TO WS-TEMP-1
    COMPUTE WS-TEMP-2 = WS-TEMP-1 * WS-TEMP-1
    MOVE WS-TEMP-2  TO LK-RESULT
    GOBACK.

よくある落とし穴と対策

① COMP-3・COMPを含むグループにMOVE ZEROSを使う

症状: COMP-3(パックドデシマル)やCOMP(バイナリ)フィールドを含むグループ項目にMOVE ZEROSすると、全バイトにゾーン数字の「0」が書き込まれ、内部表現が壊れます。そのフィールドで算術演算を行うと「DATA EXCEPTION (S0C7)」などの実行時エラーが発生します。

対策: COMP-3・COMPを含むグループは必ずINITIALIZEを使います。PIC 9(ゾーン10進)のみのグループにはMOVE ZEROSが使えますが、安全のためINITIALIZEに統一するのを推奨します。

② FILLERが初期化されず前回の値が残る

症状: INITIALIZEはデフォルトでFILLER項目を初期化しません。固定長ファイルの出力レコードにFILLERがある場合、前ループで書き込んだデータや初期化されていないゴミデータが残ったまま出力されます。

対策: 出力レコードや共有バッファの初期化にはINITIALIZE 項目名 WITH FILLERを使います。

③ VALUE句のある項目をINITIALIZEするとVALUE値に戻らない

症状: 01 WS-MAX PIC 9(2) VALUE 3.と定義されていても、通常のINITIALIZE WS-MAXはVALUE句を無視してデフォルト値の0にします。「VALUE句の初期値に戻る」と誤解すると、予期しないゼロが入ります。

対策: VALUE句の値に戻したい場合はINITIALIZE … ALL TO VALUEを使います(COBOL 2002以降対応の処理系)。対応していない処理系では明示的にMOVE 3 TO WS-MAXと書きます。

④ OCCURS配列の特定要素だけ初期化したいのに全体が変わる

症状: INITIALIZE WS-DEPT-TABLEとすると配下のすべての配列要素(OCCURS項目)が初期化されます。特定の要素だけをリセットしたいのに全件がクリアされてしまいます。

対策: 特定要素だけを初期化するときはインデックスを付けてINITIALIZE WS-DEPT-ENTRY(3)のように指定します。

⑤ REDEFINES項目を誤って二重初期化する

症状: INITIALIZE WS-DATE-FULLINITIALIZE WS-DATE-PARTSを両方書くと同じメモリ領域を2回初期化しています。意図しない場合、後から実行したほうの初期化で上書きされます。

対策: REDEFINES関係にある項目は、どちらか一方だけをINITIALIZEします。元の項目(WS-DATE-FULL)をINITIALIZEするのが明確です。

よくある質問

QINITIALIZE文とMOVE ZEROS・MOVE SPACESはどちらが高速ですか?
A一般的にMOVE ZEROS/SPACESのほうがわずかに高速です。INITIALIZEは各フィールドの型を判定してから初期化するため、純粋なメモリブロック操作より処理が多くなります。ただし差は微小なため、COMP-3を含む場合はINITIALIZEを優先してください。大量の配列を繰り返し初期化するホットパスでのみ最適化を検討する価値があります。
QINITIALIZE文で複数の項目を一度に初期化できますか?
Aはい。INITIALIZE WS-ITEM-A WS-ITEM-B WS-ITEM-Cのように空白区切りで複数指定できます。それぞれが独立して初期化されます。関連する項目をグループ項目にまとめてあれば、1つのINITIALIZEで済むためより簡潔です。
QLINKAGE SECTIONの項目をINITIALIZEできますか?
ACOBOL規格上はINITIALIZEの対象をLINKAGE SECTIONに指定すること自体は文法的に許容されますが、LINKAGE SECTIONは呼び元のメモリ領域を参照しているため、INITIALIZEすると呼び元の変数が変わります。意図しない動作になるため、原則として呼び先でLINKAGE項目をINITIALIZEしてはいけません。初期化が必要なら呼び元でINITIALIZEしてから渡します。
QINITIALIZE後にすぐVALUEで定義した初期値を使いたい場合はどうすればよいですか?
ACOBOL 2002以降の処理系(GnuCOBOLなど)ではINITIALIZE … ALL TO VALUEが使えます。非対応の処理系では、VALUE句の値を別の定数変数に保持しておき、MOVE文でリセットします。あるいは初期化用の段落(INIT-WORK-PARA.)を作り、その中でMOVE文を並べる方法が伝統的な書き方です。
QINITIALIZE文はパフォーマンスに影響しますか?
A通常のバッチ処理では問題になりません。ただし何百万件ものレコードをループする処理で毎回大きなグループをINITIALIZEすると、累積して無視できないオーバーヘッドになることがあります。その場合はINITIALIZEで初期化するフィールドを最小限に絞るか、MOVE ZEROS/SPACESで代替できる箇所(COMP-3なし)はそちらを使うことを検討します。

まとめ

機能・注意点 内容
基本動作 数値→0、文字→スペース。FILLERはデフォルトで対象外
WITH FILLER FILLERも含めて初期化。出力レコードのクリアに必須
REPLACING句 特定の型だけ任意の値で初期化。指定しない型は変化なし
ALL TO VALUE VALUE句で定義した初期値に戻す(COBOL 2002以降)
COMP-3・COMPを含むグループ MOVE ZEROSは禁止。必ずINITIALIZEを使う
OCCURS配列 親グループを指定すると全要素が対象。インデックスで個別指定も可
88レベル 直接の対象外。親項目がINITIALIZEされると値が変わり真偽も変わる

INITIALIZE文は一見シンプルですが、FILLERの扱い・COMP-3への影響・VALUE句との関係など、知らないと罠になるポイントが多い命令です。COMP-3を含むグループには必ずINITIALIZEを使い、出力バッファにはWITH FILLERを付ける習慣にすることで、大半のバグを未然に防げます。

データの転送と初期化の使い分けについてはMOVE文でデータを転送する方法も合わせてご参照ください。配列の定義についてはOCCURS句完全ガイドもご確認ください。