× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.




For most RPGLE applications variables are usually declared to a level of precision that can accommodate the values necessary to prevent run time errors. Attempting to assign a value which would exceed the precision would generate a run time error such as, MCH1210,  “Receiver value too small”. Aside from this being an obvious end user error, it also exposes a less the defensive programming technique.
Should any code block cause a variable to potentially exceed it’s a precision comparing the would result to its limit is a good practice. For example when using an integer value of 10i 0, 5i 0, or 3i 0, it would be good not know specifically the limits that can be stored in each value.
Given the following code, at what point would a user error occur?
d intShort        s              3i 0
 /free
  intShort = 127;
  intShort = 128;
  intShort = 129;
  intShort = 255;
  intShort =256;
/end-free
The run time error would occur where intShort was assigned 128.
One defensive tactic to take is to wrap the assignment within a condition to prevent the runtime error from happening in the first place.
If  (intShort + 1)  > 127
  intShort += 1;
EndIf;
Although this is a good start, I’ve hard coded the value of 127 in the program. This is considered a magic number, and would be best replaced with a symbolic constant. Moreover, this technique not my idea, but instead dates back to at least 1978 per my copy of “The C Programming Language” by Kernighan and Richie.
The C language provides for a standard include member that refers to these limits. The member is QSYSINC/H.LIMITS.
<contents of  limits.h>
      * Implementation of the C include file limits.h
     d/IF NOT DEFINED(RPGLE_LIMITS)
     d/DEFINE RPGLE_LIMITS
     d LIMITS          ds                  qualified
     d SCHAR_MIN                      3i 0 inz(*loval)
     d SCHAR_MAX                      3i 0 inz(*hival)
     d UCHAR_MAX                      3u 0 inz(*hival)
     d CHAR_MIN                       3u 0 inz(*loval)
     d CHAR_MAX                       3u 0 inz(*hival)
     d SHRT_MIN                       5i 0 inz(*loval)
     d SHRT_MAX                       5i 0 inz(*hival)
     d USHRT_MAX                      5u 0 inz(*hival)
     d INT_MIN                       10i 0 inz(*loval)
     d INT_MAX                       10i 0 inz(*hival)
     d UINT_MAX                      10u 0 inz(*hival)
     d LONG_MIN                      10i 0 inz(*loval)
     d LONG_MAX                      10i 0 inz(*hival)
     d UNLONG_MAX                    10u 0 inz(*hival)
     d LONGLONG_MIN                  20i 0 inz(*loval)
     d LONGLONG_MAX                  20i 0 inz(*hival)
     d ULLONG_MAX                    20u 0 inz(*hival)
     d/ENDIF
One shortcoming of this include file in my opinion is the fact that all of these values are meticulously enumerated.
In order to translate an include file from C to RPGLE the following include file is provided:
      /end-free

My favorite part of coding RPGLE version is leveraging the system constants *loval and *hival to define the constants.
Using the include file above within your code you can then use the constants to intermediately test the results of  an assignment before making the assignment.
The code below generates a list of the actual values of each of the constants themselves.

     h dftactgrp(*no)
     h bnddir('QC2LE')
      * Prototype --------------------------------------------------
      // Message Log
     d MsgLog          pr            10I 0 ExtProc('Qp0zLprintf')
     d  szOutputStg                    *   Value OPTIONS(*STRING)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
     d                                 *   Value OPTIONS(*string:*nopass)
      /include qrpglesrc,limits
     d LF              c                   x'25'
     d intShort        s              3i 0
      /free
       *inlr = *on;
       MsgLog('SCHAR_MIN :' + %char(LIMITS.SCHAR_MIN) + LF);
       MsgLog('SCHAR_MAX :' + %char(LIMITS.SCHAR_MAX) + LF);
       MsgLog('UCHAR_MAX :' + %char(LIMITS.UCHAR_MAX) + LF);
       MsgLog('CHAR_MIN :' + %char(LIMITS.CHAR_MIN) + LF);
       MsgLog('CHAR_MAX :' + %char(LIMITS.CHAR_MAX) + LF);
       MsgLog('SHRT_MIN :' + %char(LIMITS.SHRT_MIN) + LF);
       MsgLog('SHRT_MAX :' + %char(LIMITS.SHRT_MAX) + LF);
       MsgLog('USHRT_MAX :' + %char(LIMITS.USHRT_MAX) + LF);
       MsgLog('INT_MIN :' + %char(LIMITS.INT_MIN) + LF);
       MsgLog('INT_MAX :' + %char(LIMITS.INT_MAX) + LF);
       MsgLog('UINT_MAX :' + %char(LIMITS.UINT_MAX) + LF);
       MsgLog('LONG_MIN :' + %char(LIMITS.LONG_MIN) + LF);
       MsgLog('LONG_MAX :' + %char(LIMITS.LONG_MAX) + LF);
       MsgLog('UNLONG_MAX :' + %char(LIMITS.UNLONG_MAX) + LF);
       MsgLog('LONGLONG_MIN :' + %char(LIMITS.LONGLONG_MIN) + LF);
       MsgLog('LONGLONG_MAX :' + %char(LIMITS.LONGLONG_MAX) + LF);
       MsgLog('ULLONG_MAX :' + %char(LIMITS.ULLONG_MAX) + LF);
       intShort = 127;
       if (intShort + 1) < 128;
         intShort = 128;
         intShort = 129;
       EndIf;

Erick Garske



----- Forwarded Message ----
From: Jerry Adams <Jerry@xxxxxxxxxxxxxxx>
To: RPG programming on the IBM i / System i <rpg400-l@xxxxxxxxxxxx>
Sent: Wednesday, April 1, 2009 7:56:33 AM
Subject: RE: Constants in RPG

<snip>
Amazing thing is that there are actually people who use named constants.
Everyone I have ever known just puts AField = 52;. What the hell is 52 but
most places including the current the programmers would have a fit it they
had to identify a constant. I am the only person who ever did it.
</snip>

Alan,

I agree with your comment about the ambiguity of 'AField'.  But that reminded me of when I first started learning Cobol some years ago (OK, a few decades ago).  The instructors touted it as being "self-documenting" because one could have a 35-character field name.  When I started using it (gave it up for Lent some time ago), I noticed that "veteran" Cobol programmers usually used 6-10 character field names.  Heck, we had to hand-write programs on coding sheets back then!  I doubt that I'll personally reach the 4096 character limit in RPG IV any time soon.


Jerry C. Adams
IBM System i Programmer/Analyst
--
B&W Wholesale
office: 615-995-7024
email:  jerry@xxxxxxxxxxxxxxx


As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.