*INLR and RETURN in RPG

23 Views


Excellent question! Let's clarify the difference between *INLR and RETURN in RPG, and why you often need to use both together — especially in modular ILE RPGLE programs.


โœ… Quick Summary

Term Purpose When It Happens
*INLR Tells the system to "end program and release resources" Runtime flag to clean up program
RETURN Actually exits the program or procedure Execution control ends current scope

๐Ÿง  What Each Does

1. *INLR = *ON

  • LR = Last Record (historical term)

  • Signals that:

    • Files can be closed

    • Resources can be released

    • Static storage is freed

  • Applies only at the end of a module, not a subprocedure

  • Has no effect by itself unless followed by RETURN

2. RETURN

  • Exits the current program or subprocedure

  • Without *INLR = *ON, it leaves the program resident in memory

  • Used alone in ILE means:

    • Files stay open

    • Static variables keep their values

    • Memory is not cleaned up


๐Ÿ”ฅ Why You Need Both Together

*inlr = *on;
return;

This combination:

  • โœ… Closes all files

  • โœ… Releases all memory used by the program

  • โœ… Exits cleanly

If you do only one:

๐Ÿ”ธ return only:

  • Program stays resident

  • Next call to the program shares the same ODP, variables, file pointers

  • Can cause bugs like:

    • READ returns wrong record

    • Files appear already open

    • Static variables keep old values

๐Ÿ”ธ *inlr = *on only:

  • Does nothing unless followed by return or program naturally ends


๐Ÿงช Example

dcl-f SALESF usage(*input);

dcl-s counter int(5) static;

// Reads first record and keeps file open
read SALESF;
counter += 1;
dsply ('Counter = ' + %char(counter));

// Cleanup
*inlr = *on;
return;

If you omit *INLR = *ON, next time you call the program:

  • It starts at record 2 (not 1)

  • counter starts from previous value


๐Ÿ›  Best Practices

When Use
End of main RPGLE program *inlr = *on; return;
Subprocedure Just return; (no *INLR needed)
Service program No *INLR; keep memory alive
Batch job Always use both to ensure cleanup

Let’s build a code demo that clearly shows the impact of using (or not using) *INLR = *ON in an RPGLE program — specifically how it affects:

  • File pointer (ODP)

  • Static variables


๐Ÿงพ Demo Setup: File SALESF

A          R SALESREC
A            SALEID     5A
A            AMOUNT     9P 2
A          K SALEID

Sample data:

SALEID AMOUNT
S001 100.00
S002 200.00
S003 300.00

๐Ÿงพ Program: SALESDEMO

ctl-opt dftactgrp(*no) actgrp(*caller);

dcl-f SALESF usage(*input);

dcl-s counter int(5) static;

read SALESF;
if not %eof(SALESF);
   counter += 1;
   dsply ('READ SALEID: ' + SALEID);
   dsply ('COUNTER VALUE: ' + %char(counter));
else;
   dsply 'EOF';
endif;

// Optional cleanup โ€” comment/uncomment to test effect
*inlr = *on;
return;

๐Ÿงช Test Procedure

  1. Run CALL SALESDEMO multiple times, commenting or uncommenting the *INLR = *ON line.

  2. Observe the difference in:

    • What record is read

    • What value counter holds


๐Ÿ” Scenario A: Without *INLR = *ON

// *inlr = *on;   <--- commented out
return;

Run 1:

READ SALEID: S001
COUNTER VALUE: 1

Run 2:

READ SALEID: S002
COUNTER VALUE: 2

Run 3:

READ SALEID: S003
COUNTER VALUE: 3

โžก ODP and counter are persisting across calls. You're not starting fresh.


โœ… Scenario B: With *INLR = *ON

*inlr = *on;
return;

Every Run:

READ SALEID: S001
COUNTER VALUE: 1

โžก Program resets file pointer and static variables on every call.
ODP is destroyed, static memory is released.


๐Ÿง  Summary

Behavior Without *INLR With *INLR
File pointer persists โœ… Yes โŒ No
Static variables persist โœ… Yes โŒ No
Memory reused across calls โœ… Yes โŒ No
Risk of bugs โœ… High โœ… Low

 

Post Comments