SBMJOB時のCALL 引数その１

# SBMJOB時のCALL 引数の仕様
SBMJOB時のCALL 引数の仕様には以下の言及がある。しかし、IBMi(V7R2,V7R5で検証)実際の挙動は少し違ったりする。

- [IBMi-V7R5 : プログラム呼び出し(CALL)](https://www.ibm.com/docs/ja/i/7.5?topic=ssw_ibm_i_75/cl/call.html)

>例10:パラメーターのタイプおよび長さの省略時値を使用する新規ジョブでのプログラムの呼び出し
>> SBMJOBコマンドの実行時に定数に変換されます。
>> ...中略...
>> 文字定数が，（変数値の長さが32未満の場合，左寄せで，ブランクが埋め込まれて）渡されます。
>> ...中略...
>> 呼び出し先プログラムで最初のパラメーターが50バイトとして渡されることが予期されている場合，33バイト目から50バイト目までが参照されると，問題が生じます。
>> ...中略...
>> 値は数値定数に変換され，合計15桁，小数部5桁のパック10進数値として渡されます。


例えば以下の様な CLLE コーディングの時

```clle:USC_SBMJ11
PGM                                                                
     DCL VAR(&@PSTR1 )  TYPE(*CHAR) LEN(01  )         /* 文字列 */ 
     DCL VAR(&@PSTR2 )  TYPE(*CHAR) LEN(50  )         /* 文字列 */ 
     DCL VAR(&@PDEC1 )  TYPE(*DEC ) LEN(08 0)         /* 数値   */ 

     CHGVAR  VAR(&@PSTR1 ) VALUE('+             
                                 U+             
                                ')              
                                                
     CHGVAR  VAR(&@PSTR2 ) VALUE('+             
                                 ABCDEFGHIJ+    
                                 KLMNOPQRST+    
                                 abcdefghij+    
                                 klmnopqrst+    
                                 uvwxyzZYXW+    
                                ')              
                                                
     CHGVAR  VAR(&@PDEC1 ) VALUE(+              
                                 12345678+      
                                )               
                                                
                                                
     SBMJOB     CMD(                          + 
                 CALL USHIDA/USC_SBMJ12       + 
                      PARM(                   + 
                           &@PDEC1            + 
                           &@PSTR1            + 
                           &@PSTR2            + 
                      )                       +    
                ) JOBQ(QBATCH)                

```

```clle:USC_SBMJ12
PGM PARM(                   +                                      
         &@PDEC1            +                                      
         &@PSTR1            +                                      
         &@PSTR2            +                                      
    )                       +                                      
                                                                   
                                                                   
     DCL VAR(&@PSTR1 )  TYPE(*CHAR) LEN(01  )         /* 文字列 */ 
     DCL VAR(&@PSTR2 )  TYPE(*CHAR) LEN(50  )         /* 文字列 */ 
     DCL VAR(&@PDEC1 )  TYPE(*DEC ) LEN(08 0)         /* 数値   */ 
     DMPCLPGM                          
                                       
     SNDPGMMSG  MSG('&@PSTR1 を参照 ') 
     IF COND(&@PSTR1 *EQ ' ') THEN(DO) 
     ENDDO                             
                                       
     SNDPGMMSG  MSG('&@PSTR2 を参照 ') 
     IF COND(&@PSTR2 *EQ ' ') THEN(DO) 
     ENDDO                             
                                       
     SNDPGMMSG  MSG('&@PDEC1 を参照 ') 
     IF COND(&@PDEC1 *EQ 1) THEN(DO)   
     ENDDO                             
                                       
     ENDPGM                            
```

## 文字列引数の挙動

この言及によると `&@PSTR1` と `&@PSTR2` は両方とも **32バイト** 定数に変換され、`USC_SBM12` はエラーを発生させそうだが、実際はそうではなく。ダンプを見る限り、文字列引数は、綺麗に渡されている。

```text:CLダンプ_QPPGMDMP
 変数                   タイプ      長さ           値                            16 進値                                      
                                                   *...+....1....+....2....+     * . . . + . . . . 1 . . . . + . . . . 2 . . .
&@PDEC1                  *DEC           8 0        1234567                                                                    
&@PSTR1                  *CHAR            1       'U'                            E4                                           
&@PSTR2                  *CHAR           50       'ABCDEFGHIJKLMNOPQRSTabcde'    C1C2C3C4C5C6C7C8C9D1D2D3D4D5D6D7D8D9E2E381828
                                    +26           'fghijklmnopqrstuvwxyzZYXW'    86878889919293949596979899A2A3A4A5A6A7A8A9E9E
```

## 数値引数の挙動

一方数値はというと `&@PDEC1` は言及通り ***15桁-小数部5桁のパック10進数の定数*** に変換されており **おかしな事** になっている。そのため `USC_SBM12` は実際に次のような10進数エラーを発生する。
![2022-11-11_175943.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/3c16e782-626c-27e5-75e8-7480e9c2ae43.png)

そしてこれを回避するには、受け取りパラメータを `TYPE(*DEC) LEN(15 5)` で定義する必要がある。そうすれば、以下のように正しく数値が渡る。この辺りは、結構 **IBM i** 特有の魔物が潜んでいる事があるので気をつけましょう。