为何数据结构(DS)完全为空时IF条件仍判定为FALSE?
为何数据结构(DS)完全为空时IF条件仍判定为FALSE?
嘿,这个坑我之前踩过!问题出在RPGLE编译器对带pos()指定位置的DS的默认处理逻辑上——你以为自己只定义了两个空白字段,但编译器悄悄给你加了几个你没声明的字段,这些字段里藏着非空白的值,导致整个DS根本不是全空白的!
先看你写的DS定义:
dcl-ds source inz; *n char(4) pos(2); //will be usually blank *n char(2) pos(8); //will be usually blank end-ds;
你本来只想抓data里pos(2-5)和pos(8-9)的空白部分,但编译器会自动把DS当成连续的完整结构来处理:
- 从pos(1)到你第一个字段的pos(2)之间有空缺,编译器会自动加一个
*n char(1) pos(1)的字段; - 第一个字段到第二个字段之间(pos(6-7))也有空缺,编译器又自动加了一个
*n char(2) pos(6)的字段。
所以实际生成的DS是这样的:
dcl-ds source inz; *n char(1) pos(1); *n char(4) pos(2); //will be usually blank *n char(2) pos(6); *n char(2) pos(8); //will be usually blank end-ds;
再看你的data值:'z zz zzz',对应位置的字符是:
- pos(1):
z(非空白) - pos(6-7):
zz(非空白)
当你执行source = data;时,这两个自动生成的字段会被赋值为z和zz,所以整个source里有非空白字符,自然if source = *blanks;的条件就不成立了!
怎么解决?
有两种常用的思路:
只定义你需要的字段,避免自动填充
用qualified关键字定义DS,再配合overlay直接关联到data的对应位置,这样DS里只会有你声明的字段,不会有编译器自动加的冗余内容:dcl-ds source qualified inz; blank1 char(4) overlay(data:2); // 对应pos(2)的4位 blank2 char(2) overlay(data:8); // 对应pos(8)的2位 end-ds; // 检查两个字段是否都为空白 if source.blank1 = *blanks and source.blank2 = *blanks; dsply '指定位置都是空白'; endif;明确跳过不需要的位置
如果一定要用pos()的方式,就得把所有空缺位置都用*N显式跳过,确保这些位置的字段被初始化为空白:dcl-ds source inz; *n char(1) pos(1) inz(*blanks); // 显式跳过pos(1),初始化为空白 *n char(4) pos(2); *n char(2) pos(6) inz(*blanks); // 显式跳过pos(6-7),初始化为空白 *n char(2) pos(8); end-ds;不过这种方式比较繁琐,字段多的话很容易出错,不太推荐。
总结一下:编译器的自动填充逻辑是为了保证DS结构的连续性,但恰恰是这个特性导致了你遇到的问题。用qualified+overlay的方式能更精准地控制你要的字段,避免这种意外~
备注:内容来源于stack exchange,提问作者ojay
相关产品推荐
相关产品推荐

