更新旧RPGLE代码时遇含符号/压缩型值的数据结构行为问题咨询
RPGLE中符号型/压缩型数据结构与*ZEROS比较的特殊行为解析
嘿,这个坑我之前踩过!你肯定是发现单独用符号型(S)或者压缩型(P)变量和*ZEROS比较时完全正常,但把它们放进数据结构后,直接拿整个数据结构和*ZEROS判断就不生效了,对吧?
先把你的代码贴出来方便大家理解:
D #SIGNED S 5S 0 INZ D #PACKED S 5P 0 INZ D*--- D #AS_1 DS D #AS1 LIKE(#SIGNED) INZ D #AS2 LIKE(#SIGNED) INZ D #AS3 LIKE(#SIGNED) INZ D #AP_1 DS D #AP1 LIKE(#PACKED) INZ D #AP2 LIKE(#PACKED) INZ D #AP3 LIKE(#PACKED) INZ C C* 单个符号型变量时,该判断成立 C #AS1 IFEQ *ZEROS C EXSR MYSR C ENDIF C C* 单个压缩型变量时,该判断成立 C #AP1 IFEQ *ZEROS C EXSR MYSR C ENDIF
问题根源
这里的核心差异在于单个变量比较和整个数据结构比较的逻辑完全不同:
- 当你比较单个S/P型变量和
*ZEROS时,RPGLE做的是数值比较——它会识别变量的类型,只检查数值部分是否为零,哪怕符号位有标记(比如压缩型零的符号位是F表示正号),也会判定相等。 - 但如果你直接拿整个数据结构和
*ZEROS比较,RPGLE会执行二进制逐字节比对。而S/P型字段哪怕数值是零,符号位也会在二进制存储里占据非零的位(比如5S0的零,二进制里符号位是正号标记,不是全零),导致整个数据结构的二进制内容不是全零,自然和*ZEROS不相等。
哪怕你给数据结构字段加了INZ初始化,也只是把字段初始化为带正号的零,它的二进制依然不是全零,所以还是过不了*ZEROS的判断。
解决办法
有几种靠谱的处理方式:
- 逐个字段判断:不要偷懒直接比整个数据结构,把每个字段单独和
*ZEROS比较,用AND连接,比如:C #AS1 IFEQ *ZEROS C AND #AS2 IFEQ *ZEROS C AND #AS3 IFEQ *ZEROS C EXSR MYSR C ENDIF - 封装子过程:如果数据结构字段很多,可以写一个专门的子过程(或者LE函数),遍历数据结构的所有字段逐个检查是否为零,这样代码更整洁。
- 避免全数据结构二进制比较:除非你确定数据结构里全是无符号的字符型/数值型,否则不要直接拿数据结构和
*ZEROS做比对,这种方式在RPGLE里很容易踩类型相关的坑。
内容的提问来源于stack exchange,提问作者Mustapha George
相关产品推荐
相关产品推荐

