• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Thinking In Pointers

    September 11, 2013 Ted Holt

    Suppose you were to ask me how large an alphanumeric variable should be, and I replied that I didn’t know, nor did I care. Wouldn’t that sound odd? Those of us who have been programming in business languages such as RPG, COBOL, and CL since the French and Indian War always think it’s important to know the size of a variable, otherwise we won’t be able to define it properly in a program. But when you work with pointers, a variable’s defined size doesn’t necessarily matter. Let me show you what I’m talking about.

    Consider a command:

    CMD        PROMPT('Do something')
    PARM       KWD(OBJECT) TYPE(*CHAR) LEN(10) MAX(12) +
                 EXPR(*YES) PROMPT('List of objects')
    

    Here’s the parameter list of the CL command-processing program.

    pgm parm(&inList)
    

    How long must &inList be? At least 122 bytes, in order to allow for a maximum of 12 elements. The first two bytes contain a binary number, the value of which is the number of elements in the list. The remainder of the parameter consists of 10-byte values. Twelve times 10 bytes per element of the list, plus two bytes for the binary prefix, is 122.

    pgm parm(&inList)
    
       dcl    &inList     *char   122
    

    The command processor may send 122 bytes to the program, or it may send fewer than 122 bytes. For instance, if the user keys in three object names, the command processor will send 32 bytes to the program, and it is important that the program not access the memory assigned to bytes 33 through 122.

    Here is the not-quite-complete command-processing program, written in CL.

    pgm parm(&inList)
       dcl    &inList        *char   122
    
       dcl    &Ndx           *int    2
       dcl    &ListSize      *int    2
       dcl    &Offset        *int    2
       dcl    &CurElement    *char  10
    
       chgvar &ListSize      %bin(&inList 1 2)
       chgvar &Offset        3
    
       dofor  &Ndx from(1) to(&ListSize)
           chgvar &CurElement    %sst(&inList &Offset 10)
    
           /* do something with &CurElement */
    
           chgvar &Offset        (&Offset + 10)
       enddo
    

    Each iteration of the DOFOR loop retrieves the next list value into variable &CurElement. The program does something with &CurElement, but whatever it does is irrelevant to this discussion.

    One day someone decides that 12 occurrences are not enough. You double the value of the MAX parameter, to 24.

    CMD        PROMPT('Test list processing')
    PARM       KWD(OBJECT) TYPE(*CHAR) LEN(10) MAX(24) +
                 EXPR(*YES) PROMPT('List of names')
    

    Now you have to modify the CL program. Let’s see. The &inList variable must be assigned the value of 24 times 10, plus 2, or 242.

    Now permit me to encourage you to think about programming in a way you may not be accustomed to. (This may be analogous to asking a native speaker of English to think in Chinese, but bear with me.)

    When we process the list, how many bytes of the list do we care about at any one time? The answer is 10. We never care about more than 10 bytes at any one time.

           chgvar &CurElement    %sst(&inList &Offset 10)
    
           /* do something with &CurElement */
    

    So why define a 122-byte variable when 10 bytes will suffice? Look at this version of the same command-processing program.

    pgm parm(&inList)
    
       dcl    &inList        *char   1
    
       dcl    &pInList       *ptr
       dcl    &ListSize      *int    2  stg(*based) basptr(&pInList)
       dcl    &pElement      *ptr
       dcl    &CurElement    *char  10  stg(*based) basptr(&pElement)
       dcl    &Ndx           *int    2
    
       chgvar &pInList             %addr(&inList)
       chgvar &pElement            &pInList
       chgvar %offset(&pElement)  (%offset(&pElement) + 2)
    
       dofor  &Ndx from(1) to(&ListSize)
    
           /* do something with &CurElement */
    
           chgvar %offset(&pElement)  (%offset(&pElement) + 10)
       enddo
    

    The &inList variable has been defined with a length of 1, which is clearly and incontrovertibly inaccurate. I’ve defined it that way because I don’t care what the length of the complete list is. All I care about is the parameter’s address in memory.

    Notice that I’ve defined two pointer variables–&pInList and &pElement. Let’s look at the role of &pInList first.

    The first Change Variable (CHGVAR) command sets &pInList to the memory address of parameter &inList. Since variable &ListSize is based on &pInList, &ListSize also points to the area of memory where the list begins. Since the first two bytes of the parameter contain the number of elements in the list, the value of &ListSize, then, is the number of elements in the list.

    The values in the list begin in position three of the list, so that’s the reason for the next two CHGVAR commands. Since &CurElement is based on &pElement, the value of &CurElement is the value of the first value in the list when the DOFOR begins. Each iteration of the loop advances the &pElement 10 bytes, which makes &CurElement overlay the next element in the list.

    At the risk of belaboring the point, here’s my attempt at an illustration.

    Suppose someone runs this command as follows:

    DOIT OBJECT(SQUEEZLE PUCKERT SNOOFLE GRIPPICK)
    

    Suppose also that the system loads the list into memory at address 101. Here are the contents of memory.

    Address

    Value

    101 – 102

    0004

    103 – 112

    SQUEEZLE

    113 – 122

    PUCKERT

    123 – 132

    SNOOFLE

    133 – 142

    GRIPPICK

    Variable &pInList is 101. At the beginning of each iteration of the loop, &pElement has the values 103, 113, 123 and 133.

    And what change must be made to this program when the MAX value in the command is increased from 12 to 24? Why, none at all! Is that fine, or what?

    By the way, if this example looks familiar, you may have seen it in an article I wrote about RPG and basing pointers. See the Related Story below for details.

    Pointers are unfamiliar territory to many programmers, but they don’t have to be. Learn to use them. Besides being useful, they’re also fun!

    RELATED STORY

    Basing Pointer Variables in RPG: The Basics



                         Post this story to del.icio.us
                   Post this story to Digg
        Post this story to Slashdot

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    Raz-Lee Security

    Raz-Lee Security is the leader in security and compliance solutions that guard business-critical information on IBM i servers. We are committed to providing the best and most comprehensive solutions for compliance, auditing, and protection from threats and ransomware. We have developed cutting-edge solutions that have revolutionized analysis and fortification of IBM i servers.

    Raz-Lee’s flagship iSecurity suite of products is comprised of solutions that help your company safeguard and monitor valuable information assets against intrusions. Our state-of-the-art products protect your files and databases from both theft and extortion attacks. Our technology provides visibility into how users access data and applications, and uses sophisticated user tracking and classification to detect and block cyberattacks, unauthorized users and malicious insiders.

    With over 35 years of exclusive IBM i security focus, Raz-Lee has achieved outstanding development capabilities and expertise. We work hard to help your company achieve the highest security and regulatory compliance.

    Key Products:

    • AUDIT
    • FIREWALL
    • ANTIVIRUS
    • ANTI-RANSOMWARE
    • MULTI-FACTOR AUTHENTICATION
    • AP-JOURNAL
    • DB-GATE
    • FILESCOPE
    • COMPLIANCE MANAGER
    • FIELD ENCRYPTION

    Learn about iSecurity Products at https://www.razlee.com/isecurity-products/

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    Maxava:  FREE Webinar: Test your DR without Downtime. September 12
    Shield Advanced Solutions:  HA4i ~ High Availablity for the IBM i. FREE 30-day trial
    System i Developer:  Upgrade your skills at the RPG & DB2 Summit in Minneapolis, Oct 15-17.

    More IT Jungle Resources:

    System i PTF Guide: Weekly PTF Updates
    IBM i Events Calendar: National Conferences, Local Events, and Webinars
    Breaking News: News Hot Off The Press
    TPM @ The Reg: More News From ITJ EIC Timothy Prickett Morgan

    Kisco Unveils the Newly Renamed iFileUtility Slices Of i For The Little Guys

    Leave a Reply Cancel reply

Volume 13, Number 17 -- September 11, 2013
THIS ISSUE SPONSORED BY:

SEQUEL Software
WorksRight Software
American Top Tools

Table of Contents

  • Retrieve The Call Stack In DB2 For i
  • Thinking In Pointers
  • Admin Alert: Six Tips For Managing IBM i Spooled File Storage

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • Power Systems Did Indeed Grow Revenues Last Year
  • The IBM Power Trap: Three Mistakes That Leave You Stuck
  • Big Blue Decrees Its 2023 IBM Champions
  • As I See It: The Good, the Bad, And The Mistaken
  • IBM i PTF Guide, Volume 25, Number 5
  • N2i Gains Traction Among IBM i Newbies
  • Realizing The Promise Of Cross Platform Development With VS Code
  • 2023 IBM i Predictions, Part 3
  • Four Hundred Monitor, January 25
  • Join The 2023 IBM i Marketplace Survey Webinar Tomorrow

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2022 IT Jungle

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.