COBOLで複数のプログラムモジュールを組み合わせる際、データをどう受け渡すかが設計の要になります。CALL文でサブプログラムを呼び出すのは基本ですが、引数の渡し方にはBY REFERENCE・BY CONTENT・BY VALUEの3種類があり、それぞれ動作が異なります。
この記事では、LINKAGE SECTIONの定義方法から引数の渡し方の違い、動的CALLと静的CALLの使い分け、RETURN-CODEによる戻り値処理まで、COBOLの引数まわりを完全に解説します。
- LINKAGE SECTIONの定義ルールと注意点
- BY REFERENCE・BY CONTENT・BY VALUEの動作と使い分け
- 複数引数・グループ項目・OCCURS配列の渡し方
- 動的CALLと静的CALLの違いとメモリ管理
- RETURN-CODEとON EXCEPTIONによる異常処理
- 実践3パターン(税計算・バリデーション・件数返却)
COBOLの引数渡しの全体像
COBOLでは、呼び出し元(呼び元プログラム)がCALL文のUSING句で引数を指定し、呼び出し先(サブプログラム)がLINKAGE SECTIONとPROCEDURE DIVISION USING句で受け取ります。
IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN-PGM.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-AMOUNT PIC 9(7)V99.
01 WS-TAX-RATE PIC V9(2). *> 小数: 0.10 = 10%
01 WS-TAX-AMT PIC 9(7)V99.
PROCEDURE DIVISION.
MOVE 15000.00 TO WS-AMOUNT
MOVE .10 TO WS-TAX-RATE *> 10% = 0.10
CALL 'TAXCALC' USING WS-AMOUNT
WS-TAX-RATE
WS-TAX-AMT
DISPLAY '消費税額: ' WS-TAX-AMT
STOP RUN.
IDENTIFICATION DIVISION.
PROGRAM-ID. TAXCALC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-WORK PIC 9(10)V99.
LINKAGE SECTION. *> 引数受け取り専用セクション
01 LK-AMOUNT PIC 9(7)V99. *> USING 1番目
01 LK-TAX-RATE PIC 9(3)V2. *> USING 2番目
01 LK-TAX-AMT PIC 9(7)V99. *> USING 3番目
PROCEDURE DIVISION USING LK-AMOUNT
LK-TAX-RATE
LK-TAX-AMT.
COMPUTE LK-TAX-AMT = LK-AMOUNT * LK-TAX-RATE / 100
GOBACK.
LINKAGE SECTIONは呼び元のデータ領域に対する「別名(エイリアス)定義」です。サブプログラム内で独立したメモリを持つわけではなく、呼び元のアドレスを参照します。そのため、LINKAGE SECTION内の項目にVALUE句で初期値を設定してもコンパイルエラーになるか無視されます。
LINKAGE SECTIONの定義ルール
LINKAGE SECTIONは呼び出し先プログラムのDATA DIVISIONに記述します。定義の順序はCALL文のUSING句と一致させる必要があります。
| ルール | 説明 |
|---|---|
| レコード番号 | 01〜49・66・77・88が使用可能。01レベルまたは77レベルで宣言するのが一般的 |
| 型の一致 | 呼び元と呼び先でPIC句の桁数・型を一致させる(不一致はデータ破損の原因) |
| VALUE句 | 使用不可(コンパイラによりエラーまたは無視) |
| OCCURS句 | 可変長OCCURS(DEPENDING ON)はサポートに差異あり。固定OCCURSは使用可能 |
| FILLER項目 | 定義可能。ただし実際に参照されないため意味はない |
| REDEFINES | LINKAGE SECTION内でのREDEFINESは使用可能(呼び元の構造に合わせた再定義) |
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-WORK PIC 9(5).
LINKAGE SECTION.
*> 77レベル(単純な数値・文字)
77 LK-CODE PIC X(4).
*> 01レベル(グループ項目)
01 LK-CUSTOMER.
05 LK-CUST-ID PIC 9(10).
05 LK-CUST-NAME PIC X(40).
05 LK-CUST-AGE PIC 9(3).
*> 配列(固定OCCURS)
01 LK-SCORES.
05 LK-SCORE PIC 9(5) OCCURS 10 TIMES.
PROCEDURE DIVISION USING LK-CODE
LK-CUSTOMER
LK-SCORES.
サブプログラム内でセッションをまたいで保持したいデータはWORKING-STORAGEに置きます。LINKAGE SECTIONは「呼び元から渡されたアドレスを参照する」だけの定義領域です。「保存用はWS、受け取り用はLK」という命名規則を徹底すると混乱を防げます。
引数の渡し方3種類
COBOLの引数渡しには3つのモードがあります。BY REFERENCEがデフォルトで、用途に応じて使い分けます。
| 渡し方 | 内部動作 | 呼び元への変更反映 | 用途 |
|---|---|---|---|
| BY REFERENCE (省略時デフォルト) |
アドレスを渡す | あり(呼び元に反映) | 入出力引数 |
| BY CONTENT | 値のコピーを渡す | なし(呼び元に影響しない) | 入力専用引数 |
| BY VALUE | スタックに値を積む | なし | C言語との連携・システムAPI呼び出し |
BY REFERENCE(参照渡し)
引数のメモリアドレスを渡します。サブプログラム側で値を変更すると、呼び元の変数が直接書き換わります。最もよく使われるモードです。
*> 省略(デフォルトでBY REFERENCE)
CALL 'SUBPGM' USING WS-DATA1 WS-DATA2.
*> 明示的に指定
CALL 'SUBPGM' USING BY REFERENCE WS-DATA1
BY REFERENCE WS-DATA2.
*--- サブプログラム側での変更は呼び元に反映される ---
*SUBPGM:
PROCEDURE DIVISION USING LK-DATA1 LK-DATA2.
MOVE 'UPDATED' TO LK-DATA1. *> 呼び元WS-DATA1も'UPDATED'になる
GOBACK.
BY CONTENT(値渡し・コピー)
引数のコピー(複製)を渡します。サブプログラムがデータを変更しても呼び元には影響しません。入力専用として渡す場合に使います。
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-INPUT PIC X(20) VALUE 'ORIGINAL'.
01 WS-RESULT PIC X(20).
PROCEDURE DIVISION.
CALL 'FORMATTER' USING BY CONTENT WS-INPUT *> 入力専用
BY REFERENCE WS-RESULT *> 出力用
DISPLAY WS-INPUT. *> 'ORIGINAL'のまま(変更されていない)
DISPLAY WS-RESULT. *> サブプログラムが加工した結果
STOP RUN.
*--- FORMATTER サブプログラム ---
LINKAGE SECTION.
01 LK-INPUT PIC X(20).
01 LK-RESULT PIC X(20).
PROCEDURE DIVISION USING LK-INPUT LK-RESULT.
MOVE LK-INPUT TO LK-RESULT.
INSPECT LK-RESULT CONVERTING SPACES TO '*'. *> 加工
*> LK-INPUTを変更してもBY CONTENTなので呼び元に反映されない
GOBACK.
BY VALUE(値渡し・スタック経由)
値をスタックに積んで渡します。COBOL間では使用頻度が低く、主にC言語など他言語とのインターフェース(CEEやシステムAPI)で使います。
*> C言語のint型関数を呼び出す例(IBM Enterprise COBOL想定)
CALL 'C-FUNC' USING BY VALUE WS-NUMERIC-PARAM
BY REFERENCE WS-RESULT-PARAM.
*> リテラルをBY VALUEで渡すことも可能
CALL 'SYS-API' USING BY VALUE 1
BY VALUE ZERO.
- サブプログラムで値を変更し、呼び元に返したい → BY REFERENCE
- 入力専用で誤った上書きを防ぎたい → BY CONTENT
- C言語など他言語APIとの連携 → BY VALUE
同一CALL文で引数ごとに異なるモードを混在させることができます。
複数引数・グループ項目・配列の渡し方
グループ項目をまるごと渡す
グループ項目(01レベルの構造体)はそのままUSING句に指定できます。サブプログラム側でもグループ項目として受け取るか、グループ内の集合体として受け取るか選択できます。
*=== 呼び元 ===
WORKING-STORAGE SECTION.
01 WS-ORDER.
05 WS-ORDER-ID PIC 9(10).
05 WS-ITEM-CODE PIC X(8).
05 WS-QTY PIC 9(5).
05 WS-UNIT-PRICE PIC 9(7)V99.
01 WS-TOTAL-PRICE PIC 9(9)V99.
PROCEDURE DIVISION.
MOVE 1001 TO WS-ORDER-ID
MOVE 'ITEM-A' TO WS-ITEM-CODE
MOVE 3 TO WS-QTY
MOVE 1200.00 TO WS-UNIT-PRICE
CALL 'ORDERCALC' USING WS-ORDER *> グループ項目ごと渡す
WS-TOTAL-PRICE
STOP RUN.
*=== サブプログラム ===
LINKAGE SECTION.
01 LK-ORDER.
05 LK-ORDER-ID PIC 9(10).
05 LK-ITEM-CODE PIC X(8).
05 LK-QTY PIC 9(5).
05 LK-UNIT-PRICE PIC 9(7)V99.
01 LK-TOTAL PIC 9(9)V99.
PROCEDURE DIVISION USING LK-ORDER LK-TOTAL.
COMPUTE LK-TOTAL = LK-QTY * LK-UNIT-PRICE
GOBACK.
OCCURS配列を渡す
配列(OCCURS句)を含む項目を渡す場合も、親グループ項目をUSINGに指定します。要素数(DEPENDING ON用変数)を別引数で渡す方法がよく使われます。
*=== 呼び元 ===
WORKING-STORAGE SECTION.
01 WS-SCORE-TABLE.
05 WS-SCORE PIC 9(3) OCCURS 50 TIMES.
01 WS-SCORE-COUNT PIC 9(2) VALUE 5.
01 WS-AVERAGE PIC 9(3)V99.
PROCEDURE DIVISION.
MOVE 80 TO WS-SCORE(1)
MOVE 90 TO WS-SCORE(2)
MOVE 75 TO WS-SCORE(3)
MOVE 88 TO WS-SCORE(4)
MOVE 95 TO WS-SCORE(5)
CALL 'AVGCALC' USING WS-SCORE-TABLE
WS-SCORE-COUNT
WS-AVERAGE
DISPLAY '平均点: ' WS-AVERAGE
STOP RUN.
*=== サブプログラム ===
LINKAGE SECTION.
01 LK-SCORE-TABLE.
05 LK-SCORE PIC 9(3) OCCURS 50 TIMES.
01 LK-COUNT PIC 9(2).
01 LK-AVERAGE PIC 9(3)V99.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-SUM PIC 9(6).
01 WS-IDX PIC 9(2).
PROCEDURE DIVISION USING LK-SCORE-TABLE LK-COUNT LK-AVERAGE.
MOVE 0 TO WS-SUM
PERFORM VARYING WS-IDX FROM 1 BY 1
UNTIL WS-IDX > LK-COUNT
ADD LK-SCORE(WS-IDX) TO WS-SUM
END-PERFORM
COMPUTE LK-AVERAGE = WS-SUM / LK-COUNT
GOBACK.
動的CALLと静的CALL
CALLには静的CALLと動的CALLがあります。実行環境や保守性の要件に応じて使い分けます。
| 種類 | CALL先の指定 | リンク方式 | 特徴 | 用途 |
|---|---|---|---|---|
| 静的CALL | リテラル(文字列定数) | リンク時に結合 | 起動高速、モジュール入れ替え不可 | 固定モジュール呼び出し |
| 動的CALL | データ名(変数) | 実行時にロード | 起動に若干のオーバーヘッド、モジュール交換可能 | 複数パターンの切り替え、プラグイン的な設計 |
*=== 静的CALL(プログラム名はリテラル)===
CALL 'TAXCALC' USING WS-AMOUNT WS-RATE WS-TAX.
*=== 動的CALL(プログラム名は変数)===
WORKING-STORAGE SECTION.
01 WS-MODULE-NAME PIC X(8).
PROCEDURE DIVISION.
*> 条件によって呼び出しモジュールを切り替える
IF WS-REGION = 'JP'
MOVE 'TAXCALCJ' TO WS-MODULE-NAME
ELSE
MOVE 'TAXCALCE' TO WS-MODULE-NAME
END-IF
CALL WS-MODULE-NAME USING WS-AMOUNT WS-RATE WS-TAX
ON EXCEPTION
DISPLAY 'モジュールが見つかりません: ' WS-MODULE-NAME
MOVE 'NG' TO WS-STATUS
END-CALL.
動的CALLでロードされたモジュールは、CANCEL文を使って明示的にメモリから解放できます。長時間稼働するバッチで多数の動的モジュールを呼び出す場合、CANCEL文を使わないとメモリが圧迫されることがあります。
CANCEL 'TAXCALC'.CANCEL後に再度CALLすると再初期化された状態でロードされます。WORKING-STORAGEの値もリセットされます。
RETURN-CODEとON EXCEPTIONで結果を受け取る
サブプログラムの処理結果は引数で返すほか、RETURN-CODE特殊レジスタを使う方法があります。ON EXCEPTIONはCALLが失敗した場合(モジュール未存在など)に処理を分岐させます。
RETURN-CODEによる戻りコード
*=== サブプログラム: 処理結果をRETURN-CODEで返す ===
PROCEDURE DIVISION USING LK-INPUT LK-OUTPUT.
*> 正常処理
MOVE LK-INPUT TO LK-OUTPUT
INSPECT LK-OUTPUT CONVERTING LOWER-ALPHA TO UPPER-ALPHA
MOVE 0 TO RETURN-CODE. *> 正常: 0
GOBACK.
*> 異常時は0以外をセット
ERROR-EXIT.
MOVE 8 TO RETURN-CODE. *> 異常: 8(業務慣習に合わせて定義)
GOBACK.
*=== 呼び元: RETURN-CODEを確認する ===
PROCEDURE DIVISION.
CALL 'VALIDATE' USING WS-INPUT WS-OUTPUT
EVALUATE RETURN-CODE
WHEN 0
DISPLAY '正常終了'
WHEN 4
DISPLAY '警告あり'
WHEN 8
DISPLAY '処理エラー'
GO TO ERROR-EXIT
WHEN OTHER
DISPLAY '予期せぬエラー: ' RETURN-CODE
GO TO ERROR-EXIT
END-EVALUATE.
ON EXCEPTIONとNOT ON EXCEPTION
CALL 'PROCMODULE' USING BY REFERENCE WS-DATA
BY CONTENT WS-CTRL
BY REFERENCE WS-RESULT
ON EXCEPTION
*> モジュールが見つからない・ロード失敗時に実行
DISPLAY 'CALLエラー: PROCMODULE が見つかりません'
MOVE 'NG' TO WS-STATUS
MOVE 99 TO RETURN-CODE
NOT ON EXCEPTION
*> CALL成功時に実行(任意)
MOVE 'OK' TO WS-STATUS
END-CALL.
- 0: 正常終了
- 4: 警告(処理は継続可能だが注意あり)
- 8: 異常(処理エラー、呼び元で判断が必要)
- 12以上: 重大エラー(即時中断)
数値の意味はプロジェクト標準で統一しておくと保守性が高まります。
実践パターン3選
消費税計算モジュール(入力専用+出力引数)
金額と税率を入力専用(BY CONTENT)で渡し、計算結果を出力用引数(BY REFERENCE)で返すパターンです。
IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN-BATCH.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PRICE PIC 9(7)V99.
01 WS-TAX-RATE PIC V9(2) VALUE .10. *> 0.10 = 10%
01 WS-TAX PIC 9(7)V99.
01 WS-TOTAL PIC 9(8)V99.
PROCEDURE DIVISION.
MOVE 18000.00 TO WS-PRICE
CALL 'TAXSUB' USING BY CONTENT WS-PRICE *> 入力専用
BY CONTENT WS-TAX-RATE *> 入力専用
BY REFERENCE WS-TAX *> 出力(税額)
BY REFERENCE WS-TOTAL *> 出力(税込合計)
DISPLAY '税抜: ' WS-PRICE
DISPLAY '消費税: ' WS-TAX
DISPLAY '税込合計: ' WS-TOTAL
STOP RUN.
IDENTIFICATION DIVISION.
PROGRAM-ID. TAXSUB.
DATA DIVISION.
LINKAGE SECTION.
01 LK-PRICE PIC 9(7)V99.
01 LK-RATE PIC V9(2). *> 呼び元と同じPIC句
01 LK-TAX PIC 9(7)V99.
01 LK-TOTAL PIC 9(8)V99.
PROCEDURE DIVISION USING LK-PRICE LK-RATE LK-TAX LK-TOTAL.
COMPUTE LK-TAX = LK-PRICE * LK-RATE *> 15000.00 * 0.10 = 1500.00
COMPUTE LK-TOTAL = LK-PRICE + LK-TAX
MOVE 0 TO RETURN-CODE
GOBACK.
入力バリデーションモジュール(RETURN-CODEで結果返却)
入力値を検証して、問題があればRETURN-CODEに非0をセットして返すパターンです。引数が増えないのでCALL文がシンプルになります。
CALL 'INPUTCHK' USING BY REFERENCE WS-INPUT-DATA
ON EXCEPTION
DISPLAY 'バリデーションモジュールが見つかりません'
STOP RUN
END-CALL
IF RETURN-CODE NOT = 0
DISPLAY '入力エラー: コード=' RETURN-CODE
GO TO INPUT-ERROR
END-IF.
IDENTIFICATION DIVISION.
PROGRAM-ID. INPUTCHK.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-NUM-CHECK PIC X(1).
LINKAGE SECTION.
01 LK-INPUT-DATA.
05 LK-CUST-ID PIC 9(10).
05 LK-AMOUNT PIC S9(9)V99.
05 LK-CATEGORY PIC X(2).
PROCEDURE DIVISION USING LK-INPUT-DATA.
*> 顧客IDが0はNG
IF LK-CUST-ID = ZEROS
MOVE 4 TO RETURN-CODE
GOBACK
END-IF
*> 金額が負数はNG
IF LK-AMOUNT < 0
MOVE 8 TO RETURN-CODE
GOBACK
END-IF
*> カテゴリコードの値チェック
EVALUATE LK-CATEGORY
WHEN '01' WHEN '02' WHEN '03'
CONTINUE
WHEN OTHER
MOVE 12 TO RETURN-CODE
GOBACK
END-EVALUATE
MOVE 0 TO RETURN-CODE
GOBACK.
件数カウントモジュール(入力ファイルパスと出力件数)
ファイル名を受け取り、レコードを読んで件数を返すパターンです。ファイルアクセス処理を別モジュールに集約できます。
WORKING-STORAGE SECTION.
01 WS-FILE-NAME PIC X(40).
01 WS-REC-COUNT PIC 9(7).
01 WS-ERR-STATUS PIC X(2).
PROCEDURE DIVISION.
MOVE '/data/input/orders.dat' TO WS-FILE-NAME
CALL 'FILECNT' USING BY CONTENT WS-FILE-NAME
BY REFERENCE WS-REC-COUNT
BY REFERENCE WS-ERR-STATUS
EVALUATE RETURN-CODE
WHEN 0
DISPLAY '件数: ' WS-REC-COUNT
WHEN 4
DISPLAY 'ファイルが空です'
WHEN 8
DISPLAY 'ファイルオープンエラー: ' WS-ERR-STATUS
END-EVALUATE
STOP RUN.
IDENTIFICATION DIVISION.
PROGRAM-ID. FILECNT.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ORDER-FILE ASSIGN TO LK-FILE-NAME
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD ORDER-FILE.
01 ORDER-RECORD PIC X(200).
WORKING-STORAGE SECTION.
01 WS-FILE-STATUS PIC X(2).
01 WS-EOF-FLAG PIC X(1) VALUE 'N'.
88 WS-EOF VALUE 'Y'.
LINKAGE SECTION.
01 LK-FILE-NAME PIC X(40).
01 LK-COUNT PIC 9(7).
01 LK-ERR-STATUS PIC X(2).
PROCEDURE DIVISION USING LK-FILE-NAME LK-COUNT LK-ERR-STATUS.
MOVE 0 TO LK-COUNT
MOVE 'N' TO WS-EOF-FLAG
OPEN INPUT ORDER-FILE
IF WS-FILE-STATUS NOT = '00'
MOVE WS-FILE-STATUS TO LK-ERR-STATUS
MOVE 8 TO RETURN-CODE
GOBACK
END-IF
PERFORM UNTIL WS-EOF
READ ORDER-FILE
AT END SET WS-EOF TO TRUE
NOT AT END ADD 1 TO LK-COUNT
END-READ
END-PERFORM
CLOSE ORDER-FILE
IF LK-COUNT = 0
MOVE 4 TO RETURN-CODE
ELSE
MOVE 0 TO RETURN-CODE
END-IF
GOBACK.
よくある落とし穴と対策
| 落とし穴 | 問題の内容 | 対策 |
|---|---|---|
| 型不一致(PIC句の桁数ズレ) | 呼び元PIC 9(5)・呼び先PIC 9(7) のように桁数が違うと、LINKAGE SECTIONでアドレス計算がずれてデータ破損が発生する | COPY句でデータ定義を共有し、呼び元と呼び先で同一PIC句を使う |
| BY REFERENCEの意図しない上書き | サブプログラムが引数を変更する想定がなかったのに、誤ってMOVEしてしまい呼び元のデータが壊れる | 入力専用引数にはBY CONTENTを明示して誤上書きを防ぐ |
| LINKAGE SECTIONにVALUE句を書く | VALUE句は無視されるかコンパイルエラー。LINKAGE SECTIONは初期化の場所ではない | 初期値は呼び元で設定してから渡す。または呼び先のWORKING-STORAGEで管理する |
| 動的CALL後のCANCEL忘れ | ループ内で動的CALLを繰り返すとロードされたモジュールのWORKING-STORAGEが初期化されず、前回の残存値が混入する | 毎回再初期化が必要な場合はCALL後にCANCELを実行するか、BY REFERENCEで初期化フラグを渡す |
| RETURN-CODEの上書き | CALLの直後に別のCALLをするとRETURN-CODEが上書きされる | CALL直後にRETURN-CODEをWORKING-STORAGEの変数に退避してから判定する |
WORKING-STORAGE SECTION.
01 WS-RC1 PIC S9(9) COMP.
01 WS-RC2 PIC S9(9) COMP.
PROCEDURE DIVISION.
CALL 'SUBPGM1' USING WS-DATA1
MOVE RETURN-CODE TO WS-RC1 *> すぐに退避
CALL 'SUBPGM2' USING WS-DATA2
MOVE RETURN-CODE TO WS-RC2 *> すぐに退避
IF WS-RC1 NOT = 0
DISPLAY 'SUBPGM1エラー: ' WS-RC1
END-IF
IF WS-RC2 NOT = 0
DISPLAY 'SUBPGM2エラー: ' WS-RC2
END-IF.
よくある質問
まとめ
COBOLの引数まわりのポイントをまとめます。
| 要素 | 説明 |
|---|---|
| LINKAGE SECTION | サブプログラム側で引数を定義するセクション。呼び元のアドレスを参照する別名定義 |
| BY REFERENCE(デフォルト) | アドレス渡し。サブプログラムでの変更が呼び元に反映される |
| BY CONTENT | コピー渡し。入力専用引数の保護に使う |
| BY VALUE | スタック渡し。主に他言語連携で使う |
| 動的CALL | 変数でモジュール名を指定。ON EXCEPTIONでロード失敗を検知できる |
| RETURN-CODE | サブプログラムが設定する戻りコード。CALLの直後に退避して使う |
| GOBACK | サブプログラムの終了命令。呼び元に制御を返す(STOP RUNと混同しない) |
引数の渡し方をしっかり設計することで、モジュール間のデータ連携が明確になり、テストや保守が格段にしやすくなります。BY CONTENTで入力専用を明示し、RETURN-CODEで処理結果を返す設計を習慣にしましょう。
COBOLのデータ操作については、MOVE文でデータを転送する方法や、CALL文の基本的な使い方も合わせてご参照ください。引数の流れを理解した上でUSING句の詳細な仕様を確認すると、より深く理解できます。