3 Ensuring Readability

This chapter contains the following topics:

3.1 Understanding Readability

Readable code is easier to debug and maintain. You can make code more readable by maintaining the change log, inserting comments, indenting code, and formatting compound statements.

3.2 Maintaining the Source and Header Code Change Log

You must note any code changes that you make to the standard source and header for a business function. Include this information:

  • SAR - the SAR number

  • Date - the date of the change

  • Initials - the programmer's initials

  • Comment - the reason for the change

3.3 Inserting Comments

Insert comments that describe the purpose of the business function and your intended approach. Using comments will make future maintenance and enhancement of the function easier.

Use this checklist for inserting comments:

  • Always use the /*comment */ style. The use of // comments is not portable.

  • Precede and align comments with the statements they describe.

  • Comments should never be more that 80 characters wide.

3.3.1 Example: Inserting Comments

This example shows the correct way to insert block and inline comments into code:

 /*----------------------------------------------------------
 * Comment blocks need to have separating lines between
 * the text description. The separator can be a
 * dash '-' or an asterisk '*'
 *----------------------------------------------------------*/
 if ( statement )
 {
    statements
 } /* inline comments indicate the meaning of one statement */
 /*----------------------------------------------------------
 * Comments should be used in all segments of the source
 * code. The original programmer may not be the programmer
 * maintaining the code in the future which makes this a
 * crucial step in the development process.
 *----------------------------------------------------------*/
 /************************************************************
 * Function Clean Up
 ************************************************************/

3.4 Indenting Code

Any statements executed inside a block of code should be indented within that block of code. Standard indentation is three spaces.

Note:

Set up the environment for the editor you are using to set tab stops at 3 and turn the tab character display off. Then, each time you press the Tab key, three spaces are inserted rather than the tab character. Select auto-indentation.

3.4.1 Example: Indenting Code

This the standard method to indent code:

function block
{
   if ( nJDEDBReturn == JDEDB_PASSED )
   {
      CallSomeFunction( nParameter1, szParameter2 );
      CallAnotherFunction( lSomeNumber );
      while( FunctionWithBooleanReturn() )
      {
         CallYetAnotherFunction( cStatusCode );
      }
   }
}

3.5 Formatting Compound Statements

Compound statements are statements followed by one or more statements enclosed with braces. A function block is an obvious example of a compound statement. Control statements (while, for) and selection statements (if, switch) are also examples of compound statements.

Omitting braces is a common C coding practice when only one statement follows a control or selection statement. However, you must use braces for all compound statements for these reasons:

  • The absence of braces can cause errors.

  • Braces ensure that all compound statements are treated the same way.

  • In the case of nested compound statements, the use of braces clarifies the statements that belong to a particular code block.

  • Braces make subsequent modifications easier.

Refer to these guidelines when formatting compound statements:

  • Always have one statement per line within a compound statement.

  • Always use braces to contain the statements that follow a control statement or a selection statement.

  • Braces should be aligned with the initial control or selection statement.

  • Logical expressions evaluated within a control or selection statement should be broken up across multiple lines if they do not fit on one line. When breaking up multiple logical expressions, do not begin a new line with the logical operator; the logical operator must remain on the preceding line.

  • When evaluating multiple logical expressions, use parentheses to explicitly indicate precedence.

  • Never declare variables within a compound statement, except function blocks.

  • Use braces for all compound statements.

  • Place each opening or closing brace, { or }, on a separate line.

3.5.1 Example: Formatting Compound Statements

This example shows how to format compound statements for ease of use and to prevent mistakes:

/*
 * Do the Issues Edit Line if the process edits is either
 * blank or set to SKIP_COMPLETIONS. The process edits is
 * set to SKIP_COMPLETIONS if Hours and Quantities is in
 * interactive mode and Completions is Blind in P31123.
 */
if ((dsWorkCache.PO_cIssuesBlindExecution == _J('1')) &&
   ((dsCache.cPayPointCode == _J('M'))      ||
    (dsCache.cPayPointCode == _J('B')))       &&
   (lpDS->cProcessEdits != ONLY_COMPLETIONS))
{
   /* Process the Pay Point line for Material Issues */
   idReturnCode = I3101060_BlindIssuesEditLine(&dsInternal,
                                               &dsCache,
                                               &dsWorkCache);
}

3.5.2 Example: Using Braces to Clarify Flow

This example shows the use of braces to clarify the flow and prevent mistakes:

if(idJDBReturn != JDEDB_PASSED)
{
   /* If not add mode, record must exist */
   if ((lpdsInternal->cActionCode != ADD_MODE) &&
       (lpdsInternal->cActionCode != ATTACH_MODE)) 
   {
      /* Issue Error 0002 - Work Order number invalid */
      jdeStrncpy((JCHAR*)(lpdsInternal->szErrorMessageID),
                 (const JCHAR*)_J(0002),
                 DIM(lpdsInternal->szErrorMessageID)-1);
      lpdsInternal->idFieldID = IDERRmnOrderNumber_15;
      idReturnCode = ER_ERROR;
   }
}
else
{
   /* If in add mode and the record exists, issue error and exit */
   if (lpdsInternal->cActionCode == ADD_MODE)
   {
      /* Issue Error 0002 - Work Order number invalid */
      jdeStrncpy((JCHAR*)(lpdsInternal->szErrorMessageID),
                 (const JCHAR*)_J(0002),
                 DIM(lpdsInternal->szErrorMessageID)-1);
      lpdsInternal->idFieldID = IDERRmnOrderNumber_15;
      idReturnCode = ER_ERROR;
   }
   else
   {
      /*
       * Set flag used in determining if the F4801 record should be sent
       * in to the modules
       */
       lpdsInternal->cF4801Retrieved = _J('1');
   }
}

3.5.3 Example: Using Braces for Ease in Subsequent Modifications

The use of braces prevents mistakes when the code is later modified. Consider this example. The original code contains a test to see if the number of lines is less than a predefined limit. As intended, the return value is assigned a certain value if the number of lines is greater than the maximum. Later, someone decides that an error message should be issued in addition to assigning a certain return value. The intent is for both statements to be executed only if the number of lines is greater than the maximum. Instead, idReturn will be set to ER_ERROR regardless of the value of nLines. If braces were used originally, this mistake would have been avoided.

ORIGINAL

if (nLines > MAX_LINES)
   idReturn = ER_ERROR;

MODIFIED

if (nLines > MAX_LINES)
   jdeErrorSet (lpBhvrCom, lpVoid,
               (ID) 0, _J(4353), (LPVOID) NULL);
   idReturn = ER_ERROR;

STANDARD ORIGINAL

if (nLines > MAX_LINES)
{
   idReturn = ER_ERROR;
}

STANDARD MODIFIED

if (nLines > MAX_LINES)
{
   jdeErrorSet (lpBhvrCom, lpVoid,
               (ID) 0, _J(4363), (LPVOID) NULL);
   idReturn = ER_ERROR;
}

3.5.4 Example: Handling Multiple Logical Expressions

This example shows how to handle multiple logical expressions:

while ( (lWorkArray[elWorkX] < lWorkArray[elWorkMAX]) &&
        (lWorkArray[elWorkX] < lWorkArray[elWorkCDAYS]) &&
        (idReturnCode == ER_SUCCESS))


{
   statements
}