> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codeant.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Rpg

<AccordionGroup>
  <Accordion title="Imported data items should not be updated">
    <div class="paragraph">
      <p>`IMPORT`ed values should be treated as read-only. Doing otherwise could result in unpleasant surprises down the line.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D VAR2             S              5  0 IMPORT
      * Noncompliant
      C           MOVE       MYVAR     VAR2

      C/FREE
      // Noncompliant
      VAR2=MYVAR;
      /END-FREE
      ```

      ```rpg Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Debugging statements DEBUG(*YES) and DUMP should not be used">
    <div class="paragraph">
      <p>The <code>DEBUG(\*YES) and DUMP</code> statements are useful during development and debugging, but could expose sensitive information to attackers and should not be included in production code.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      H*------------------------------------------------------------------------- 
      H   DATEDIT(*YMD) DEBUG(*YES)                                               
      H**************************************************************************

      C     SR990         BegSR                                                                   
      C     'CVTERR'      DUMP                                                   DUMP for error
      C                   Move      *on           *INLR
      ```

      ```rpg Fix theme={null}
      H*------------------------------------------------------------------------- 
      H   DATEDIT(*YMD) 
      H**************************************************************************

      C     SR990         BegSR                                                                   
      C                   Move      *on           *INLR
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Procedures should have return values">
    <div class="paragraph">
      <p>Even if there’s no data to be returned from a procedure, each procedure should at least return a boolean to indicate when procedure execution failed, so callers can respond accordingly.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D MyProc          PI
       D   param1                      10A   const
        /free
          // do work...
          return;  // Noncompliant
        /end-free
      ```

      ```rpg Fix theme={null}
      D MyProc          PI              N
       D   param1                      10A   const
        /free
          // do work...
          return *ON;
        /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="The correct ENDxx statement should be used">
    <div class="paragraph">
      <p>While \`END will adequately close a statement, it is less clear than the use of the relevant, statement-specific ENDxx. Thus, the statement-specific version is preferred to facilitate code maintenance and enhance clarity.</p>
    </div>

    <div class="paragraph">
      <p>This rule is applied to the following operations: CASxx, DO, DOU, DOUxx, DOW, DOWxx, FOR, IF, IFxx and SELECT\` groups.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C     W0PKEX        DOUEQ     W0ON   
      ...
      C                   END     

      C     W0PKEX        IFEQ      W0ON   
      ...
      C                   END
      ```

      ```rpg Fix theme={null}
      /free
      if x = 1;
      ...
      end;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Expressions should not be too complex">
    <div class="paragraph">
      <p>The complexity of an expression is defined by the number of <code>AND, OR</code>.</p>
    </div>

    <div class="paragraph">
      <p>A single expression’s complexity should not become too high to keep the code readable.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   IF        (condition1 AND condition2)
      C                             OR (condition2 AND condition2)
      C                             OR (condition3 AND condition4)
      ```

      ```rpg Fix theme={null}
      /free
      IF A=X OR A=Y AND A=Z AND B=Y OR B=Z;
          ...
      ENDIF;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="MONITOR statements with identical ON-ERROR blocks should be merged">
    <div class="paragraph">
      <p>When multiple, adjacent <code>MONITOR statements have duplicate ON-ERROR blocks, they should be merged to consolidate the ON-ERROR logic for cleaner, more readable code. Note that this applies even when there is intervening code outside any MONITOR</code> block.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      /free
      monitor; 
        // do something...
      on-error;
        CALLP HandleError(*param);
      endmon;

      // do un-monitored thing

      monitor;
        // do something else...
      on-error;  // Noncompliant
        CALLP HandleError(*param);
      endmon;
      /end-free
      ```

      ```rpg Fix theme={null}
      /free
      monitor; 
        // do something...
        // do un-monitored thing
        // do something else...
      on-error;
        CALLP HandleError(*param);
      endmon;
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Labels should be on lines by themselves">
    <div class="paragraph">
      <p>Shared coding conventions allow teams to collaborate effectively. This rule checks that labels are on lines by themselves, which makes them more immediately visible as such.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      LBLVAL:    IF         COND(&ERRFLG = ' ') THEN (DO)
             CHGVAR     VAR(&MSG) VALUE('Validation Completed')
             ENDDO
      ```

      ```rpg Fix theme={null}
      LBLVAL:
             IF         COND(&ERRFLG = ' ') THEN (DO)
             CHGVAR     VAR(&MSG) VALUE('Validation Completed')
             ENDDO
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Record formats  should be cleared before each use">
    <div class="paragraph">
      <p>The format used to write a record to a file should be cleared before each use. Otherwise stale data left in the format from previous records may be saved into the current record if it does not have data for all the fields in the format.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   IF        X <> Y
      ...
      C                   ENDIF       
      C                   WRITE     RECFMT
      ```

      ```rpg Fix theme={null}
      /free
      if x <> y;
      ...
      endif;
      write recfmt;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="ON-ERROR clauses should not be empty">
    <div class="paragraph">
      <p>Leaving an <code>ON-ERROR</code> block empty means that the exception in question is neither handled nor passed forward to callers for handling at a higher level. Suppressing errors rather than handling them could lead to unpredictable system behavior and should be avoided.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      /free
          monitor;
            // ...
            on-error *FILE; // Noncompliant
          endmon;
        /end-free
      ```

      ```rpg Fix theme={null}
      /free
          monitor;
            // ...
            on-error *FILE;
              handleFileError();
          endmon;
        /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="UNDERLINE should not be used">
    <div class="paragraph">
      <p>The use of <code>UNDERLINE makes normal text printed to the screen difficult to read, and prevents titles from being read at all. For these reasons, UNDERLINE</code> should not be used.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      R DETAIL1
        * Noncompliant; next line contains UNDERLINE
         NAME          25      2  2UNDERLINE
         ADD1          25      3  2
       R DETAIL3
         ADD2          25         2SPACEB(1)
      ```

      ```rpg Fix theme={null}
      R DETAIL1
         NAME          25      2  2
         ADD1          25      3  2
       R DETAIL3
         ADD2          25         2SPACEB(1)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="The parameters of a CALL or CALLB statement should be defined as a PLIST">
    <div class="paragraph">
      <p>Using a unique symbolic \`PLIST name provides a single definition point for the parameters used by any external routine being called. This ensures that the same information is passed every time the external routine is called, reducing the potential for mistakes in operation.</p>
    </div>

    <div class="paragraph">
      <p>This rule flags non-compliant instances of CALL and CALLB\`.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   CALLB(D)  'XR01'
      C                   PARM                    WSXR07
      C                   PARM                    WSFLD1
      ```

      ```rpg Fix theme={null}
      C     P0XR07        PLIST                               
      C                   PARM                    WSXR07       
      C                   PARM                    WSFLD1 

      C                   CALLB     'XR07'        P0XR07
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Track lack of copyright and license headers">
    <div class="paragraph">
      <p>Each program should contain an initial section of <code>H\*</code> comments lines, which includes a copyright and/or license statement. This rule must be fed with the header text that is expected in the header.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      H*  Copyright (C) 2008-2013 SonarSource
       H*  mailto:contact AT sonarsource DOT com
       H*  
       H*  SonarQube is free software; you can redistribute it and/or
       H*  modify it under the terms of the GNU Lesser General Public
       H*  License as published by the Free Software Foundation; either
       H*  version 3 of the License, or (at your option) any later version.
       H*  
       H*  SonarQube is distributed in the hope that it will be useful,
       H*  but WITHOUT ANY WARRANTY; without even the implied warranty of
       H*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       H*  Lesser General Public License for more details.
       H*  
       H*  You should have received a copy of the GNU Lesser General Public License
       H*  along with this program; if not, write to the Free Software Foundation,
       H*  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
      ```

      ```rpg Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="/COPY should be avoided">
    <div class="paragraph">
      <p>Historically <code>/COPY procedures contained all of the specifications required for each procedure, so for example xxxxF /COPY would be used to copy the F lines from another F spec. However, this practice results in code that is difficult to understand and maintain. Instead, the use of /COPY</code> statements should be replaced with explicit declarations.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      F/COPY HRSILERPG,RSX36
      ```

      ```rpg Fix theme={null}
      FSSINRTP   IF   E           K DISK    INFSR(*PSSR) 
      F*                                                 
      F*  Interest Rates File                             
      F*
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="The *srcstmt header option should be used">
    <div class="paragraph">
      <p>Turning on the \`\*srcstmt header option means that any line numbers cited in error statements will actually correspond correctly to the code. Otherwise, object line numbers will be shown, making errors difficult to debug.</p>
    </div>

    <div class="paragraph">
      <p>The \*srcstmt option is also recommended for accurate line numbers during debugging, particularly in combination with \*nodebugio, (H option(\*srcstmt:\*nodebugio)\`) which prevents debug operations from stopping on I/O.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      H*
      H* AMENDED BY : G. Ann Campbell
      H* DATE       : 16JUL2014      
      H* H24 - Miscellaneous Online Maintenance/Enquiry/Printing
      H*
      F/EJECT
      ```

      ```rpg Fix theme={null}
      H*
      H* AMENDED BY : G. Ann Campbell
      H* DATE       : 16JUL2014      
      H* H24 - Miscellaneous Online Maintenance/Enquiry/Printing
      H*
      H option(*srcstmt)
      F/EJECT
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="All opened USROPN files should be explicitly closed">
    <div class="paragraph">
      <p>If a file is defined without the `USROPN statement then the natural RPG logic will deal with opening and closing it. However, files defined with USROPN, must be both explicitly OPENed and CLOSE`d.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      FEWPCCR1   O    E             PRINTER USROPN           
      F                                     INFDS(WSFD01)   
      F                                     INFSR(*PSSR)     

      C                   OPEN      EWPCCR1   

      C                   CLOSE     *ALL
      ```

      ```rpg Fix theme={null}
      FEWPCCR1   O    E             PRINTER USROPN           
      F                                     INFDS(WSFD01)   
      F                                     INFSR(*PSSR)     

      /free
      open  EWPCCR1;
      close *ALL;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Spacing types should not be mixed">
    <div class="paragraph">
      <p>Using both <code>SPACEA (space-after) and SPACEB</code> (space-before) in the same printer file can make it difficult to understand how many blank lines will be printed where. Therefore either one command or the other should be used but not both.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      A          R REP001                    TEXT('Detail line.       ')        
      A                                      SPACEB(1)                          
      A                                      SPACEA(1)                          
      A                                     2'Additional Details for Student :'
      A            VAR01          6        36TEXT('Additional Details for +     
      A                                          Student')
      ```

      ```rpg Fix theme={null}
      A          R REP001                    TEXT('Detail line.       ')        
      A                                      SPACEB(1)                                
      A                                     2'Additional Details for Student :'
      A            VAR01          6        36TEXT('Additional Details for +     
      A                                          Student')
      A                                      SPACEB(1)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Related IF/ELSEIF statements and WHEN clauses in a SELECT should not have the same condition">
    <div class="paragraph">
      <p>A <code>Select or a chain of If/Elseif statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true</code>.</p>
    </div>

    <div class="paragraph">
      <p>Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it’s simply dead code and at worst, it’s a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   IF        X = 1
       C                   EXSR      SR01
       C                   ELSEIF    X = 1                                       Noncompliant
       C                   EXSR      SR02
       C                   ENDIF
      ```

      ```rpg Fix theme={null}
      /free
       IF param = 1;
          doX();
       ELSEIF param = 2;
          doY();
       ELSEIF param = 1; // Noncompliant
          doZ();
       ENDIF;

       SELECT;
         WHEN param = 1;
           doX();
         WHEN param = 2;
           doY();
         WHEN param = 1; // Noncompliant
           doZ();
       ENDSL;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Named constants should be used for indicators">
    <div class="paragraph">
      <p>Using a named constant to refer to an indicator makes the content of the field clearer, and therefore makes the code easier to read and maintain.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D accountTotal    c                   25

        /Free

         If *In(accountTotal);
          // Process contents...
         EndIf;
      ```

      ```rpg Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Compile-time arrays should not be used">
    <div class="paragraph">
      <p>Having all the pieces in front of you makes it easier to understand and debug or maintain a piece of code. Unfortunately, that’s often not the case with compile-time arrays, since they are often separated from the code that uses them by many, many lines. Instead, data structures are often a better option.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D directions      S              5  0 dim(4) ctdata perrcd(1)
      ```

      ```rpg Fix theme={null}
      D dirData         DS
       D                                5    Inz('North')
       D                                5    Inz('South')
       D                                5    Inz('East')
       D                                5    Inz('West')
       D directions                     5    Dim(4) Overlay(dirData)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="E should be found in F-spec lines">
    <div class="paragraph">
      <p>Externally described files standardize file access, and result in simpler, easier to read code.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      FEPBLMSL2  IF   F  100        DISK    INFSR(*PSSR)                                                                                         
       F*                                                                                                                                                                                                              
       F*
      ```

      ```rpg Fix theme={null}
      F*                                                                                                                    
       FIPBDCCP   IF   E           K DISK    INFSR(*PSSR)                                                                    
       F*                                                                                                                                                                                          

       FEP210     CF   E             WORKSTN INFSR(*PSSR)                                                                 
       F                                     SFILE(EP21003S:RELN03)                                                       


       FEP471R1   O    E             PRINTER INFSR(*PSSR)                                                              
       F                                     USROPN                                                                    
       F                                     INFDS(W1SF01)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Procedures that check parameter count should mark parameters optional">
    <div class="paragraph">
      <p>Testing <code>%PARMS before the use of one or more parameters is a clear indication in the code that at least some parameters are treated as optional. However, failure to actually mark those parameters as such with options( \*nopass ) denies callers the ability to treat them as optional. Since all parameters after the first one explicitly declared options( \*nopass )</code> are also implicitly optional, this marking is only required once. However, for clarity you should consider explicitly marking all optional parameters.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      DCL-PR VIOLATION1 EXTPGM;  // Noncompliant
           LASTNAME Char(10);
           FIRSTNAME Char(10);
         END-PR;

         DCL-PI VIOLATION1;
           LASTNAME Char(10);
           FIRSTNAME Char(10);
         END-PI;

         dsply FIRSTNAME;
         IF %PARMS > 1;
           dsply LASTNAME;
         EndIf;
         *inlr = *on;
      ```

      ```rpg Fix theme={null}
      DCL-PR VIOLATION1 EXTPGM; 
           LASTNAME Char(10);
           FIRSTNAME Char(10)  options( *nopass );
         END-PR;

         DCL-PI VIOLATION1;
           LASTNAME Char(10);
           FIRSTNAME Char(10)  options( *nopass );
         END-PI;

         dsply FIRSTNAME;
         IF %PARMS > 1;
           dsply LASTNAME;
         EndIf;
         *inlr = *on;
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Optional operation codes should be omitted">
    <div class="paragraph">
      <p><code>Eval and Callp</code> are the only two exceptions to the rule that each free-format line must start with an operation code. Since you can leave these two opcodes out, you should for cleaner, more readable code.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      Eval Regpay = hours * perHour;
      Callp calcTax();
      ```

      ```rpg Fix theme={null}
      Regpay = hours * perHour;
      calcTax();
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="IF ... ELSEIF constructs should end with ELSE clauses">
    <div class="paragraph">
      <p>This rule applies whenever an \`IF statement is followed by one or more ELSEIF statements; the final ELSEIF should be followed by an ELSE statement.</p>
    </div>

    <div class="paragraph">
      <p>The requirement for a final ELSE statement is defensive programming.</p>
    </div>

    <div class="paragraph">
      <p>The ELSE statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final OTHER clause in a SELECT\` statement.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   IF         RESULT = 0
      C                   ...
      C                   ELSEIF     RESULT > 0
      C                   ...
      C                   ENDIF
      ```

      ```rpg Fix theme={null}
      /free
      if result = 0;
       ...
      elseif result > 0;
       ...
      endif;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="The first parameter of a CHAIN/READx statement should be a KLIST">
    <div class="paragraph">
      <p>Using a unique \`KLIST to access files ensures that the correct key is used at all times and creates a standard method of accessing the data throughout the code, simplifying maintenance and improving readability.</p>
    </div>

    <div class="paragraph">
      <p>This rule flags non-compliant instances of CHAIN, DELETE, READE, READPE, SETGT, and SETLL\` operations.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C     'D001 B'      CHAIN     KYCUSTN                            20
      ... 
      C     DEPT          CHAIN     KYCUSTN                            20
      ```

      ```rpg Fix theme={null}
      C     DEPTKY        KLIST
      C                   KFLD                    DEPT
      C                   KFLD                    SHIFT 

      C     DEPTKY        CHAIN     KYCUSTN                            20
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Subroutine names should comply with a naming convention">
    <div class="paragraph">
      <p>Shared naming conventions allow teams to collaborate efficiently.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue when a subroutine name does not match a provided regular expression.</p>
    </div>

    <div class="paragraph">
      <p>For example, with the default provided regular expression <code>^SR\[a-zA-Z0-9]\*\$</code>, the following subroutines:</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      C     XXXXX         BEGSR
      ...
      C                   ENDSR
      ```

      ```rpg Fix theme={null}
      /free
      begsr yyyy;
      endsr;
      /end-free{code}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Control flow statements IF, FOR, DO, ... should not be nested too deeply">
    <div class="paragraph">
      <p>Nested control flow statements <code>CASxx, DO, DOU, DOW, DOUxx, DOWxx, FOR, IF, IFxx, MONITOR and SELECT</code> are often key ingredients in creating
      what’s known as "Spaghetti code". This code smell can make your program difficult to understand and maintain.</p>
    </div>

    <div class="paragraph">
      <p>When numerous control structures are placed inside one another, the code becomes a tangled, complex web.
      This significantly reduces the code’s readability and maintainability, and it also complicates the testing process.</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      IF        A <> B
      IF        B <> C
      DOW       B <> A
      IF        A <> D
      ...
      ENDIF
      ENDDO
      ENDIF
      ENDIF
      ```

      ```rpg Fix theme={null}
      if a <> b;
      if b <> c;
      dow b <> a;
        if a <> d;
          ...
        endif;
      enddo;
      endif;
      endif;
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Numeric fields should be defined as odd length packed fields">
    <div class="paragraph">
      <p>When storing numeric fields, using an odd number of digits allows the sign to be included in the storage area without wasting any space.</p>
    </div>

    <div class="paragraph">
      <p>For example the number -1234567, when packed as 7 digits is stored as follows.</p>
    </div>

    <div class="listingblock">
      <div class="content">
        <pre>1357
        246-</pre>
      </div>
    </div>

    <div class="paragraph">
      <p>thus taking up only 4 data slots. but when packed as 8 characters it uses 5 data slots</p>
    </div>

    <div class="listingblock">
      <div class="content">
        <pre>02467
        0135-</pre>
      </div>
    </div>

    <div class="paragraph">
      <p>or when 7 digits, non-packed, it will be stored as 8 data slots, including the sign.</p>
    </div>

    <div class="listingblock">
      <div class="content">
        <pre>FFFFFFF6
        12345670</pre>
      </div>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D NUMFLD          S              8P 0 
       D NUMFLD          S              7S 0
      ```

      ```rpg Fix theme={null}
      D NUMFLD          S              7P 0
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Subprocedures should be used instead of subroutines">
    <div class="paragraph">
      <p>Subprocedures and subroutines are both mechanisms to segregate logic, but subprocedures are preferred for three reasons:</p>
    </div>

    <div class="ulist">
      <ul>
        <li>
          <p>their local files and variables make maintenance faster and cleaner. They allow you to create variables without worrying about name clashes, and to change fields without worrying about negatively impacting other parts of the program.</p>
        </li>

        <li>
          <p>their local files and variables make code reuse easy.</p>
        </li>

        <li>
          <p>they can be called with parameters as functions, yielding clearer more readable code.</p>
        </li>
      </ul>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D  FirstName      S             20A
       D  Initial        S              1A
       D  LastName       S             20A
       D  FullName       S             43A

        /free
         FirstName = 'John';
         Initial = 'A';
         LastName = 'Smith';
         EXSR SPFullName;
         DSPLY FullName;
         ...

         begsr SPFullName;
           FullName = FirstName + ' ' + Initial + ' ' + LastName;
         endsr;
        /end-free
      ```

      ```rpg Fix theme={null}
      /free
         DSPLY FullName('John':'A':'Smith');
         ...
        /end-free

       P FullName        B
       D FullName        PI            43A
       D  FirstName                    20A   Const
       D  Initial                       1A   Const
       D  LastName                     20A   Const
        /free
         return FirstName + ' ' + Initial + ' ' + LastName;
        /end-Free
       P                 E
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="/COPY statements should include specification letters">
    <div class="paragraph">
      <p>Shared coding conventions allow teams to collaborate effectively. While it is possible to omit the specification letter before a <code>/COPY</code> statement, it is advisable not to do so because including a specification on the line indicates to other developers what type of statements will be added to the program by the copybook. Further, using a specification letter on the line makes it clearer to those who might be skimming the file that the line is not just a comment, but does contain code.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      /COPY MBR1
      ```

      ```rpg Fix theme={null}
      I/COPY MBR1
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Subroutines should be documented">
    <div class="paragraph">
      <p>Every subroutine should be commented to explain its goal and how it works. This non-empty comment must be located before or after the subroutine definition.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C     SR012         BEGSR
      C                         ...
      C                   ENDSR
      ```

      ```rpg Fix theme={null}
      /free
      begsr SR012;
      ...
      endsr;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Subprocedures should not reference global variables">
    <div class="paragraph">
      <p>Global variables can seem like a handy way to pass state information around in a program, but the use of global variables only works well in very small programs. As the code base grows, you’ll need to understand every subprocedure’s impact on the global state in order to understand how the program works. This is a task that quickly becomes impossible.</p>
    </div>

    <div class="paragraph">
      <p>To control the situation, only the main procedure should be allowed access to global variables; it can then pass that state information to subprocedures as parameters.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D FirstName       S             20A     
       D LastName        S             20A   

        /free
         FirstName = 'John';
         LastName = 'Smith';
         DSPLY FullName();
        /end-free

       P FullName        B
       D FullName        PI            41A
        /free
         return FirstName + ' ' + LastName;
        /end-Free
       P                 E
      ```

      ```rpg Fix theme={null}
      /free
         DSPLY FullName('John':'Smith');
        /end-free

       P FullName        B
       D FullName        PI            41A
       D  FirstName                    20A   Const
       D  LastName                     20A   Const
        /free
         return FirstName + ' ' + LastName;
        /end-Free
       P                 E
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Error handling should be defined in F specs">
    <div class="paragraph">
      <p>Error handling should be defined on file operations to ensure correct processing of program failures rather than defaulting to an abnormal program end. This rule checks two things:</p>
    </div>

    <div class="ulist">
      <ul>
        <li>
          <p><code>INFSR</code> error handling is defined on file operations.</p>
        </li>

        <li>
          <p>error handling is delegated to an appropriately named routine.</p>
        </li>
      </ul>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      F* Noncompliant
       FIPBDCCP   IF   E           K DISK

       FEP210     CF   E             WORKSTN
       F                                     SFILE(EP21003S:RELN03)     

       FEP471R1   O    E             PRINTER 
       F                                     USROPN
       F                                     INFDS(W1SF01)
      ```

      ```rpg Fix theme={null}
      FIPBDCCP   IF   E           K DISK    INFSR(*PSSR)

       FEP210     CF   E             WORKSTN INFSR(*PSSR)
       F                                     SFILE(EP21003S:RELN03)

       FEP471R1   O    E             PRINTER INFSR(*PSSR)
       F                                     USROPN
       F                                     INFDS(W1SF01)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="GOTO statements should not be used">
    <div class="paragraph">
      <p><code>GOTO is an unstructured control flow statement. It makes code less readable and maintainable, and should only be used to branch to defined ENDSR points within the source. For normal loop functions use ITER or LEAVE</code> instead.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C     LOOP1         TAG 
      ... 
      C                   GOTO      LOOP1
      ```

      ```rpg Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="The data area structure for IN should be defined in D spec lines.">
    <div class="paragraph">
      <p>Both the name and the field definitions of a parameter 2 data area used in an <code>IN should be coded in the D</code> specification. This ensures that all definition data is kept together, and the specific data is not manually extracted in the code, thus making the code easier to read and maintain.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D WSFD08          S             30A 0                 

      C                   IN        WSFD08   
      C                   MOVEL     WSFD08        VAR9S
      ```

      ```rpg Fix theme={null}
      D WSFD08          S             30A 0                 

      /free
      in  WSFD08;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="OVERLAY should be used for overlapping fields">
    <div class="paragraph">
      <p>The use of positional notation to describe the overlapping of one field on another can quickly become confusing, particularly in large, or complicated data structures. Instead, the <code>OVERLAY</code> keyword should be used to make such overlaps more readily identifiable.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D Message         DS                  QUALIFIED
       D   Id                           7
        * Noncompliant
       D   Type                  1      3
      ```

      ```rpg Fix theme={null}
      D Message         DS                  QUALIFIED
       D   Id                           7
       D   Type                         3    OVERLAY(Id)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Calculations should use free-form syntax">
    <div class="paragraph">
      <p>Free-format syntax is preferred because it is clearer, easier to write, and easier for newcomers to the language than fixed-format syntax.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   IF        A > 10
       C                   EVAL      B = 1
       C                   ENDIF
      ```

      ```rpg Fix theme={null}
      /free
          if A > 10;
            B = 1;
          endif;
        /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="External program names should not be listed redundantly">
    <div class="paragraph">
      <p>There’s no need to repeat the program name in the free-format definition of an external program.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      DCL-PR PGM001 EXTPGM('PGM001'); 
      END-PR;
      ```

      ```rpg Fix theme={null}
      DCL-PR PGM001 EXTPGM ; 
      END-PR;
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Library names should not be hard-coded">
    <div class="paragraph">
      <p>Because library names could change from environment to environment, they should never be hard-coded in a program. Instead, you should use a variable to specify the library name and set that variable with data external to the program.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      CLRPFM   FILE(XPJLIB/FILE01)
      ```

      ```rpg Fix theme={null}
      CHGVAR     VAR(&LIB01) VALUE(&PREFIX *CAT 'LIB')
      CLRPFM      FILE(&LIB01/FILE01)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SELECT WHEN clauses should not have too many lines">
    <div class="paragraph">
      <p>The <code>SELECT statement should be used only to clearly define some new branches in the control flow. As soon as a WHEN clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of WHEN</code> clause should be extracted in a dedicated subroutine.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   SELECT
      C                   WHEN      X=1
      C                   MOVE      A             B
      C                   MOVE      C             D
      C                   MOVE      E             F
      C                   MOVE      J             K
      C                   MOVE      L             M
      C                   WHEN      X=2
      C                   ....
      C                   ENDSL
      /free
      select;
       when X=1;
         B = A;
         D = C;
         F = E;
         K = J;
         M = L;
       when X=2;
         ...
      endsl;
      /end-free
      ```

      ```rpg Fix theme={null}
      C                   SELECT
      C                   WHEN      X=1
      C                   EXSR      SR011
      C                   WHEN      X=2
      C                   ....
      C                   ENDSL
      C                   ...
      C     SR011         BEGSR
      C                   MOVE      A             B
      C                   MOVE      C             D
      C                   MOVE      E             F
      C                   MOVE      J             K
      C                   MOVE      L             M
      C                   ENDSR
      /free
      select;
       when X=1;
         exsr SR011;
       when X=2;
         ...
      endsl;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Line count data should be retrieved from the file information data structure">
    <div class="paragraph">
      <p>When using a <code>PRINTER defined file, an INFDS keyword should be used to read the file’s line count from \*PSSR</code> positions 367-368.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      FCSO602R1  O    E             PRINTER USROPN 
      or ... 
      FCSO602R1  O    E             PRINTER USROPN 
      F                                     INFDS(WSFD01) 
      F                                     INFSR(*PSSR) 

      D WSFD01          DS 
      D  W1ST01           *STATUS 
      D  W1SPNO               123    124B 0
      ```

      ```rpg Fix theme={null}
      FCSO602R1  O    E             PRINTER USROPN 
      F                                     INFDS(WSFD01) 
      F                                     INFSR(*PSSR) 

      D WSFD01          DS 
      D  W1ST01           *STATUS 
      D  W1SPNO               123    124B 0 
      D  W1LNCT               367    368B 0 
      D  W1PGNO               369    372B 0
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Non-input files should be accessed with the no lock option">
    <div class="paragraph">
      <p>When accessing a non-input-only file with a <code>CHAIN/READx operation, the record is locked and becomes inaccessible to the system, and unreadable other programs. This is fine if you are about to update the record immediately, but if you have data processing to do following the read, it can leave the record unavailable for too long. Therefore, non-input files using the CHAIN, READ, READE, READP, and READPE operation codes should always be accessed with the no lock option, (N)</code>.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      FDDDLJNL7  UF   E           K DISK    INFSR(*PSSR) 
      ... 
      C                   READ      DDDLJNL7
      ```

      ```rpg Fix theme={null}
      FDDDLJNL7  UF   E           K DISK    INFSR(*PSSR) 
      ... 
      /free
      read DDDLJNL7;
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Multiple occurrence data structures should not be used">
    <div class="paragraph">
      <p>While the <code>OCCURS keyword still works, it is slower than its more modern replacement: DIM</code>, which should be used instead.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D cussls          ds                  Occurs(200)  
      D CustNo                         7p 0                     
      D MonthlySls                    11P 2
      ```

      ```rpg Fix theme={null}
      D cussls          ds                  dim(200)   
      D CustNo                         7p 0                      
      D MonthlySls                    11P 2
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Standard figurative constants *ON, *OFF and *BLANK should be used in place of 1, 0 and  ">
    <div class="paragraph">
      <p>Initializing an alphanumeric field with the literal character <code>' ', '1', or '0' has the same effect as using the equivalent figurative constant \*BLANK, \*ON, or \*OFF</code>, but the constant version removes ambiguity and makes the code more readable.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   MOVE      ' '           FLD1
      ```

      ```rpg Fix theme={null}
      /free
      fld1 = ' ';
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Optional parameters should be checked before use">
    <div class="paragraph">
      <p>The use of <code>options( \*nopass )</code> on a parameter makes it optional, so it should always be checked before use.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      DCL-PR VIOLATION1 EXTPGM;
           LASTNAME Char(10);
           FIRSTNAME Char(10) OPTIONS(*NOPASS:*OMIT);
         END-PR;

         DCL-PI VIOLATION1;
           LASTNAME Char(10);
           FIRSTNAME Char(10) OPTIONS(*NOPASS:*OMIT);
         END-PI;

         dsply FIRSTNAME;
         dsply LASTNAME;  // Noncompliant; LASTNAME is optional
         *inlr = *on;
      ```

      ```rpg Fix theme={null}
      DCL-PR VIOLATION1 EXTPGM;
           LASTNAME Char(10);
           FIRSTNAME Char(10) OPTIONS(*NOPASS:*OMIT);
         END-PR;

         DCL-PI VIOLATION1;
           LASTNAME Char(10);
           FIRSTNAME Char(10) OPTIONS(*NOPASS:*OMIT);
         END-PI;

         dsply FIRSTNAME;
         IF %PARMS > 1;
           dsply LASTNAME;
         EndIf;
         *inlr = *on;
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Length notation should be used for data structure definitions">
    <div class="paragraph">
      <p>The use of positional notation can quickly become confusing, especially in a large or complex data structure. To keep the code clean and understandable, use length notation instead.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D PERSON          DS                  QUALIFIED
        * Noncompliant
       D  FName                  1     30
       D  LName                 31     60
      ```

      ```rpg Fix theme={null}
      D PERSON          DS                  QUALIFIED
       D  FName                        30
       D  LName                        30
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Prototypes should be used">
    <div class="paragraph">
      <p>Prototypes should be used for program calls because their use allows compile-time checking of the number of parameters and the type and size of those parameters. Without the use of a prototype, that checking happens only at run-time.</p>
    </div>

    <div class="paragraph">
      <p>A secondary benefit of the use of prototypes and <code>CALLP</code>, is that prototypes allow the caller to gain a clearer understanding of the data expected for each parameter because parameter names are purely descriptive.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      ----


      === Compliant solution

      [source,rpg]
      ```

      ```rpg Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Blank lines should not have end-of-line comments">
    <div class="paragraph">
      <p>Shared coding conventions allow teams to collaborate effectively. To improve readability, blank lines in a program should not have end-of-line comments.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      I/COPY VALSRC,VALTEST                                                FIX001
                                                                            FIX001
        ** Data structure for subroutine VALDS                              FIX001
       I            DS                                                      FIX001
       I                                        5   60MMA                   FIX001
       I                                        7   80DDA                   FIX001
        *                                                                   FIX001
       I            DS                                                      FIX001
       I                                        5   60MMB                   FIX001
       I                                        7   80DDB                   FIX001
      ```

      ```rpg Fix theme={null}
      I/COPY VALSRC,VALTEST                                                FIX001

        ** Data structure for subroutine VALDS                              FIX001
       I            DS                                                      FIX001
       I                                        5   60MMA                   FIX001
       I                                        7   80DDA                   FIX001
        *                                                                   FIX001
       I            DS                                                      FIX001
       I                                        5   60MMB                   FIX001
       I                                        7   80DDB                   FIX001
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="/EJECT should be used after F, D and C specification sections">
    <div class="paragraph">
      <p>The <code>/EJECT compiler directive adds a page break when the code is printed, and should be used at the end of each F, D, and C</code> specification section to make the structure of the code clearer and to enhance overall readability.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      F* Conversion Job Activity File (CV)                   
      F*                                                     
      FCVJBAVP   IF   E           K DISK                     
      F* Conversion Job Dependency File (CZ)                 
      F*                                                     
      FCVJBDPP   IF   E           K DISK                     
      F*                                           
      DP0RTCD           S              1                     
      DP0JBNM           S             10A                     
      DP0ERMG           S            100A                     
      DK0JBNM           S                   LIKE(CVJBNM)     
      DK1JBNM           S                   LIKE(CVJBNM)     
      DJST              S             10A   DIM(10)           
      DI                S              3  0 INZ               
      C                                                       
      C                   EXSR      SR999                     
      C                                                       
      C                   EXSR      SR100
      ```

      ```rpg Fix theme={null}
      F* Conversion Job Activity File (CV)                   
      F*                                                     
      FCVJBAVP   IF   E           K DISK                     
      F* Conversion Job Dependency File (CZ)                 
      F*                                                     
      FCVJBDPP   IF   E           K DISK                     
      F*                                           
      F/EJECT           
      DP0RTCD           S              1                     
      DP0JBNM           S             10A                     
      DP0ERMG           S            100A                     
      DK0JBNM           S                   LIKE(CVJBNM)     
      DK1JBNM           S                   LIKE(CVJBNM)     
      DJST              S             10A   DIM(10)           
      DI                S              3  0 INZ               
      D/EJECT 
      C                                                       
      C                   EXSR      SR999                     
      C                                                       
      C                   EXSR      SR100                     
      C/EJECT
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Select/omit rules should not be used">
    <div class="paragraph">
      <p><code>SELECT and OMIT allow you to choose records from a logical file based on the values of specific fields. SQL views allow you to make the same distinctions, but their use is more efficient, and easier to read and understand. Therefore views are preferred over SELECT and OMIT</code> statements.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      Index: SKCOU03

      *************** Beginning of data *************************************
        A          R SKCOU                     TEXT('Coupon Rate Details')
        A                                      PFILE(SKCOUP)
        A          K COUASS
        A          K COUEFF                    DESCEND
        A          S COUSTS                    COMP(EQ 'L')
        A          S COUSTS                    COMP(EQ 'X')

      ****************** End of data ***************************************
      ```

      ```rpg Fix theme={null}
      CREATE VIEW SKCOU03 AS
      SELECT A.COUFLD1, A.COUASS, A.COUEFF, A.COUSTS, A.COUFLD4
      FROM SKCOUP A
      where
      A.COUSTS = ‘L’ OR A.COUSTS=’X’
      Order by A.COUASS, A.COUEFF desc
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Prototypes should be used">
    <div class="paragraph">
      <p>Specifying the parameters to a procedure with a <code>PLIST makes that procedure unusable from free-format code. Instead, prototypes should be used - both when defining a procedure and when calling it. They have the additional benefit of allowing you to use keywords such as Const to better-specify how parameters are passed to a procedure. Further, the use of a prototype instead of a PLIST</code> is cleaner and  more consistent with the code required for subprocedures.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      * Noncompliant; PLIST specified
       C     *ENTRY        PLIST
       C                   PARM                    ZipCode           5 0
       C                   PARM                    City             20
      ...
        * Noncompliant; PLIST used in call
       C                   CALL      'OTHERPROG'
       C                   PARM                    ZipCode
       C                   PARM                    City
      ```

      ```rpg Fix theme={null}
      D MYPROG          PR                 
       D  ZipCode                       5I   Const
       D  City                         20A   Const
       D MYPROG          PI                 
       D  ZipCode                       5I   Const
       D  City                         20A   Const     
      ...
       D OTHERPROG       PR                  ExtPgm('OtherProgram')
       D  ZipCode                       5I   Const
       D  City                         20A   Const
        /free
          OTHERPROG(ZipCode:City);
        /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Result data structures should be used for file I/O">
    <div class="paragraph">
      <p>The use of a result data structure with file I/O improves performance because it moves the data in one large block from file to data structure (or vice versa) rather than field by field.</p>
    </div>

    <div class="paragraph">
      <p>Additionally using a data structure can limit the problems caused by having bad data in a file. Without a data structure, the entire <code>READ</code> operation will fail at the first bad value. With one, the error comes only when the bad field is used.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      F MyFile   IF   E             Disk
         * Noncompliant
       C                   READ      Record1
      ```

      ```rpg Fix theme={null}
      F MyFile   IF   E             Disk

       D InputData       DS                  LikeRec(Record1)
       C                   READ      Record1       InputData
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="IF statements should not be conditioned on Indicators">
    <div class="paragraph">
      <p>Indicators should not be used on "IF" statements because they foster poor logic flow and result in code that is difficult to read and maintain.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C   99FLD1          IFEQ      FLD2
      ```

      ```rpg Fix theme={null}
      C     FLD1          IFEQ      FLD2
      C     *IN99         ANDEQ     *ON
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Indicators should be used on CHAIN statements">
    <div class="paragraph">
      <p>A results indicator should be used on a <code>CHAIN statement because it leads to cleaner, more readable, and more correct code. Using an indicator results in the conditions record not found, and end of file</code> being automatically handled correctly, without the need for further error handling.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      C     K0GMCP        CHAIN     SSGMCPR
      ```

      ```rpg Fix theme={null}
      C     K0GMCP        CHAIN     SSGMCPR                            81
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Inz() should not be used on non-static variables">
    <div class="paragraph">
      <p>Non-static variables initialized with <code>INZ() are only reliably initialized on the first run through the code in a  "terminate and stay resident" (TSR) program. Subsequent calls to the program within the same job do not re-initialize the variable with the value from INZ()</code> unless the last record indicator is set at the end of the program.</p>
    </div>

    <div class="paragraph">
      <p>Without setting the last record indicator, the assumptions the code makes about the variable’s initial value will be wrong every time but one, potentially leading to bad program behavior.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D TESTINZ         PR                  extpgm('TESTINZ')
       D  Parm1                        15A
       D  Parm2                        15A   CONST

       DMUTVAR           S             15A   INZ('ABC')  // Noncompliant; *inlr not set

       D TESTINZ         PI
       D  Parm1                        15A
       D  Parm2                        15A   CONST
        /Free
         IF %PARMS > 1 and Parm2 <> '';
           MUTVAR=Parm2;
         ENDIF;
         DSPLY(E) ('MUTVAR:' + MUTVAR);
         Parm1=MUTVAR;
         return;
         /End-free
      ```

      ```rpg Fix theme={null}
      D TESTINZ         PR                  extpgm('TESTINZ')
       D  Parm1                        15A
       D  Parm2                        15A   CONST

       DMUTVAR           S             15A   INZ('ABC')

       D TESTINZ         PI
       D  Parm1                        15A
       D  Parm2                        15A   CONST
        /Free
         IF %PARMS > 1 and Parm2 <> '';
           MUTVAR=Parm2;
         ENDIF;
         DSPLY(E) ('MUTVAR:' + MUTVAR);
         Parm1=MUTVAR;
         *inlr = *on;
         return;
         /End-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="QUALIFIED data structures should be used">
    <div class="paragraph">
      <p><code>QUALIFIED</code> data structures result in cleaner code because you can’t reference the fields without using the qualifying name. They also  allow you to have multiple sub-fields with the same name, meaning subfield names don’t have to be convoluted for uniqueness, and can be expressive instead.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      * Noncompliant
       D Employee        DS
       D  EmpId                         7P 0
       D  EFName                       30A
       D  ELName                       30A
       D  EPhone                       11P 0

        * Noncompliant
       D Contractor      DS
       D  CntId                         7P 0
       D  CFName                       30A
       D  CLName                       30A
       D  CPhone                       11P 0

        /free
          EmpId = '000220';
        /end-free
      ```

      ```rpg Fix theme={null}
      D Employee        DS                  QUALIFIED
       D  Id                            7P 0
       D  FName                        30A
       D  LName                        30A
       D  Phone                        11P 0

       D Contractor      DS                  QUALIFIED
       D  Id                            7P 0
       D  FName                        30A
       D  LName                        30A
       D  Phone                        11P 0

        /free
          Employee.Id = '000220';
        /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="File operations should specify a file name">
    <div class="paragraph">
      <p>While a file I/O call will compile without a file name, such code is almost always an error. The omission of the file name, can cause unexpected results in multi-file programs.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      * Noncompliant
      C                   READ                    DS1                      90
      ```

      ```rpg Fix theme={null}
      C                   READ      PF0001        DS1                      90
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="LIKE keyword should be used to define work fields">
    <div class="paragraph">
      <p>Use of the LIKE statement for fields with the same specification that are being used together in the same statements makes the relevance of individual fields more understandable, and gives easy reference information, and makes relationships between those fields more obvious.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D NAME            S             20A
      D PNAM            S             20A
      ```

      ```rpg Fix theme={null}
      D NAME            S             20A
      D PNAM            S             LIKE(NAME)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="CONST should be used for parameters that are not modified">
    <div class="paragraph">
      <p>The <code>CONST keyword on a subprocedure’s parameter indicates that the parameter value will not be changed by the subprocedure. This is not just a nice way to communicate with the programmers who will call the procedure. It also offers performance benefits, because it allows the compiler to produce more optimized code. Further, using CONST</code> means that a field of a similar data type will automatically be converted to the correct type and size for the parameter.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```rpg Bad theme={null}
      D X               S             15A   INZ('ABC')

       P SubProc1        B
       D SubProc1        PI
       D  Parm1                        15A    // Noncompliant; read-only. Should be CONST
       D  Parm2                        15A
        /Free
         X = Parm1;
         Parm2 = X;
         return;
        /End-free
       P SubProc1        E
      ```

      ```rpg Fix theme={null}
      D X               S             15A   INZ('ABC')

       P SubProc1        B
       D SubProc1        PI
       D  Parm1                        15A   CONST
       D  Parm2                        15A
        /Free
         X = Parm1;
         Parm2 = X;
         return;
        /End-free
       P SubProc1        E
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Delivering code in production with debug features activated is security-sensitive">
    <div class="paragraph">
      <p>Development tools and frameworks usually have options to make debugging easier for developers. Although these features are useful during development, they should never be enabled for applications deployed in production. Debug instructions or error messages can leak detailed information about the system, like the application’s path or file names.</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      H*------------------------------------------------------------------------- 
      H   DATEDIT(*YMD) DEBUG(*YES)                                               
      H**************************************************************************

      C     SR990         BegSR                                                                   
      C     'CVTERR'      DUMP                                                   DUMP for error
      C                   Move      *on           *INLR
      ```

      ```rpg Fix theme={null}
      H*------------------------------------------------------------------------- 
      H   DATEDIT(*YMD) 
      H**************************************************************************

      C     SR990         BegSR                                                                   
      C                   Move      *on           *INLR
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Unused variables should be removed">
    <div class="paragraph">
      <p>If a private field is declared but not used locally, its limited visibility makes it dead code.</p>
    </div>

    <div class="paragraph">
      <p>This is either a sign that some logic is missing or that the code should be cleaned.</p>
    </div>

    <div class="paragraph">
      <p>Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand and preventing bugs from being introduced.</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      D I               S              5P 0      INZ
      D* Noncompliant; X is not used in C-Specs
      D X               S              5P 0      INZ

      C                   EVAL      I = I + 1
      ```

      ```rpg Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Identical expressions should not be used on both sides of a binary operator">
    <div class="paragraph">
      <p>Using the same value on both sides of a binary operator is a code defect. In the case of logical operators, it is either a copy/paste error and, therefore, a bug, or it is simply duplicated code and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results and should be simplified as well.</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   IF        X = X
      ```

      ```rpg Fix theme={null}
      /free
          if a = a; // always true
            doZ();
          endif;
          if a <> a; // always false
            doY();
          endif;
          if a = b and a = b; // if the first one is true, the second one is too
            doX();
          endif;
          if a = b or a = b; // if the first one is true, the second one is too
            doV();
          endif;

          j = 5 / 5; //always 1
          k = 5 - 5; //always 0
        /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Variables should not be self-assigned">
    <div class="paragraph">
      <p>There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      /free
          name = name;
        /end-free
      ```

      ```rpg Fix theme={null}
      /free
          customer.name = name;
        /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="String literals should not be duplicated">
    <div class="paragraph">
      <p>Duplicated string literals make the process of refactoring complex and error-prone, as any change would need to be propagated on all occurrences.</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   MOVEL     'CLEAR'       W1CLR                           Noncompliant
      C                   MOVEL     '*DECOD'      W1DCDE
      C                   MOVEL     '*ERROR'      W1ERR 
      C                   MOVEL     '*EXIT '      W1EXIT
      C                   MOVEL     'CLEAR'       W1FIRT
      C                   MOVEL     'CLEAR'       W1HELP
      ```

      ```rpg Fix theme={null}
      /free
      W1CLR = 'CLEAR'; // Noncompliant
      W1FIRT = 'CLEAR';
      W1HELP = 'CLEAR';
      /end-free
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Columns to be read with a SELECT statement should be clearly defined">
    <div class="paragraph">
      <p><code>SELECT \*</code> should be avoided because it releases control of the returned columns and could therefore lead to errors and potentially to performance issues.</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      SELECT * 
         FROM persons 
         INTO newyorkers 
         WHERE city = 'NEW YORK'
      ```

      ```rpg Fix theme={null}
      SELECT firstname, lastname 
         FROM persons 
         INTO newyorkers
         WHERE city = 'NEW YORK'
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Two branches in a conditional structure should not have exactly the same implementation">
    <div class="paragraph">
      <p>Having two WHEN in the same SELECT statement or branches in the same IF structure  with the same implementation is at best duplicate code, and at worst a coding error.</p>
    </div>

    <CodeGroup>
      ```rpg Bad theme={null}
      C                   IF        X = 1
       C                   EXSR      SR01
       C                   EXSR      SR01
       C                   ELSEIF    X = 2
       C                   EXSR      SR02
       C                   ELSEIF    X = 3
       C                   EXSR      SR01                                         Noncompliant; duplicates first condition
       C                   EXSR      SR01
       C                   ENDIF
      ```

      ```rpg Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>
