2.5.3 Programming and Source Code Standards

Introduction

  1. This Internal Revenue Manual (IRM) is organized into the following subsections:

    1. Introduction

    2. General Programming

    3. COBOL Programming

    4. C Language Programming

    5. C++ Programming

    6. Java Programming

  2. The subsection, "Introduction" introduces this Internal Revenue Manual (IRM). This subsection states the purpose of this manual, defines terms, identifies personnel affected by this manual, describes the roles mentioned in the manual, describes how this manual is organized, and identifies other documents addressed in this manual. This subsection also provides background and history about this manual.

  3. The subsection, "General Programming" addresses non-language specific general programming topics.

  4. The subsection, "COBOL Programming" addresses topics specific to COBOL programming.

  5. The subsection, "C Language Programming" addresses topics specific to C language programming.

  6. The subsection, "C++ Programming" addresses topics specific to C++ programming.

  7. The subsection, "Java Programming" addresses topics specific to Java programming.

Purpose

  1. This Internal Revenue Manual (IRM) establishes standards and guidelines to promote the development of maintainable, portable, reliable software applications in all Service used/approved languages as outlined in this IRM.

Definitions

  1. Exhibit 2.5.3-1 defines terms used in this Internal Revenue Manual.

Affected Personnel

  1. The controls established in this Internal Revenue Manual (IRM) apply to Service personnel responsible for developing or maintaining the Service's application systems or software applications, identified in the IRS Enterprise Architecture. Service personnel who contract for development or maintenance of these systems/software applications shall ensure contracts comply with these controls.

  2. These controls apply to all organizations, organizational units, and projects responsible for developing or maintaining the Service's application systems or software applications, identified in the IRS Enterprise Architecture.

References

  1. As supplement references on the development of maintainable, portable, reliable software applications, the following documents are recommended:

    • The Elements of Programming Style, ISBN: 0070342075, Brian W. Kernighan and P. J. Plauger

    • IRM 2.5.12 - Design Techniques and Deliverables, provides comprehensive standards and guidelines regarding structure charts and module specifications

    • Assembler Language Programming, ISBN: 0–471–88657–2, Nancy Stern, Alden Sager and Robert A. Stein

    • Structured COBOL Programming, ISBN 0-471-29987-1, Nancy Stern and Robert A Stern

    • The Elements of C Programming Style, ISBN 0070512787, Jay Ranade and Alan Nash

    • IRM 2.5.2 Software System Testing

    • IRS Enterprise Architecture at http://irsprime.web.irs.gov/IRSEA/default.htm

    • IRS Document 12384, C++ Programming Standards

    • Code Conventions for the Java Programming Language, Sun Microsystems, Inc.

Waivers

  1. IRM 2.5.1 Systems Development documents the waiver process.

General Programming

  1. This section of the IRM, which should be Weighed based on platform and language -specific idiosyncrasies, presents a variety of standards and guidelines to be applied to application program development and documentation efforts.

  2. The objective of this section is to promote the development of programs that are reliable, modular, easily maintainable, and as portable as possible.

  3. New software tools for application development and decision support may supplement and/or replace traditional design and programming techniques. Commercially acquired software packages may reduce development time by eliminating "detailed" design and programming activities. Off-the-shelf software packages should be carefully considered before the decision is made to develop software.

  4. The scope of this directive is Servicewide. This includes software developed by contractors. Where the guidelines apply to Assembler Language, COBOL, C Language, C++ programming, and Java programming, these guidelines shall be followed respectively.

  5. This directive is designed for use by application software developers and programmers/project developers and contractors who are responsible for development of source code and who must ensure that the proper documentation is sent to the implementation/test site.

Goals

  1. The primary goal of structured programming is to produce working programs that are modular, accurate, and self-documenting, so that they are easy to read and maintain by someone other than the original author.

  2. Structured programming includes the following activities:

    • Developing specifications for the logic of each module;

    • Writing structured code to implement the logic of the module; and

    • Using a structured testing methodology that gradually creates a working program as each module is introduced into the application system.

Basic Principles

  1. Structured programming employs the use of limited syntax (constructs) for source code, single-entry/single-exit modules, and top-down development.

  2. Base the logic of each module on various combinations of control structures. The three basic constructs are Sequence, Selection (If-Then-Else), and Repetition (Do-While)/(Test-First). Two optional constructs include Repetition (Do-Until)/(Test-Last) and Selection (Case).

  3. Exhibit 2.5.3-4 depicts a flowchart and Structure diagram for each construct. The actual implementation of these structures will vary according to the requirements of the particular language being used.

  4. Ensure that each module has only one entry point to and one exit point from the module.

  5. Partition and organize each module, program, and application system into a hierarchical structure. Structure charts, and therefore module specifications and structured code, are part of the design of a system.

Design Specifications

  1. Various tools are commonly used to communicate and transition design specifications to source code. These tools are:

    1. structure charts

    2. module specifications

    IRM 2.5.12 - Design Techniques and Deliverables, provides comprehensive standards and guidelines regarding structure charts and module specifications during design.

Documenting, Testing, and Debugging Source Code

  1. This section addresses services that should be performed regardless of the language or platform selected.

Documenting Code
  1. Document each module and paragraph for future modifications at the time of writing or review/use/modification of the code. Document the changed module and the changes.

  2. Ensure that all source code is well documented, clear, understandable, and easy to modify and maintain.

  3. Make each module a small block of source code; not exceed one page of printed output (exclusive of comments).

  4. Indent source code statements.

Testing and Debugging Code
  1. Review, analyze and test the code for consistency, correctness, clarity and completeness according to IRS coding standards.

  2. Test the software according to IRM 2.5.2 Software Systems Testing.

Selecting Programming Languages

  1. For new projects, select the programming language based on IRS Enterprise Architecture requirements.

Data Controls

  1. Data controls is knowing for what purpose a variable has been defined (ie., its type) and what functions of the program access modify a variable.

  2. This subsection provides general guidelines for developing data controls and examples of data control types that are often used in system development. This is not an all-inclusive list of controls, but rather a general framework for control development.

  3. Data controls should have one and only one purpose for each variables.

  4. Variable scope should be apparent and limited (ie., the set of program functions which can access the variable).

  5. Variables should only be "global" as necessary. Only functions which require a variable should have access to it.

  6. Data controls permit an operating entity to verify that the correct operations have been performed, in the correct manner, with the correct data.

  7. Ensure that Data control considerations comprise an integral part of the design process.

Basic Principles of Data Controls
  1. Controls refer to the manual and automated measures employed to:

    • Preserve the accuracy of data by detecting and/or preventing operator errors.

    • Ensure that no data is lost or added, by monitoring balances between processes.

    • Ensure data integrity so programs do not inadvertently change the values of data.

    • Permit the proper recovery/reconstruction of file data after a system failure or abnormal termination.

    • Safeguard sensitive data to prevent unauthorized access, embezzlement, and other breaches of security.

Programming Considerations for Data Controls
  1. Integrate controls into the development effort. The types of controls and the amount of detail are dependent upon the size and complexity of the application system.

  2. Weigh each development effort based on the following operational considerations:

    • the amount of operator intervention;

    • multi-file/multi-cartridge processing;

    • checkpoint/restart capability;

    • the file ID on all internal reports;

    • back-up of control file;

    • initialization of working storage and output buffers with spaces and zeros; and

    • run to run balancing

Data Controls
  1. Place controls as close as possible to the source of the data (e.g., verification of data immediately after it is entered; block balancing before data is released to update modules, etc.).

  2. Automate controls whenever possible.

  3. Keep controls simple to read and balance, and easy to maintain.

  4. Explain the purpose and use of controls. Describe how the totals were derived.

  5. Record counts must be provided and broken down into logical records for each run.

Internal Data Controls
  1. Internal controls are balancing procedures developed to verify the validity of the processing within a run. Internal controls are usually a response to user requirements for accuracy, completeness and security within an information system. Segment these controls into three classes:

    1. controls over input,

    2. controls over processing, and

    3. controls over output.

Input Controls
  1. Input controls are the most important and the most numerous. Most errors are generated during input processing. Some common techniques are:

    • Check digit verification--Use check digits to review the accuracy of specific fields. For example, a check digit can help determine whether an account number is valid.

    • Consistency tests--If the application permits it, verify accuracy by comparing the values of various fields to determine whether the combinations make sense. For example, if the "Country" field indicates that the record concerns an organization in Canada, the "Postal Code " field should have a specific alphanumeric format.

    • Validity tests--In some cases, fields can take only a limited range of values, or must have a predetermined format. Matching the actual value to the allowable values will detect errors. For example, if a field is supposed to contain a valid U.S. postal abbreviation for a state, "AZ " would be valid but "A2" would not.

    • Batch numbering--This technique ensures that transactions are not lost. Processor checks can be made to assure that all transactions are accounted for and processed in a logical order.

    • Control totals--These totals help avoid errors during data entry. Various input fields (e.g., check amount or quantity received) are added both manually and automatically for comparison. In some cases, these totals are developed for fields that would normally not be added (e.g., account numbers or social security numbers). These are called hash totals. In either case, both the expected totals and the individual transactions are passed to the application system. The application system then recalculates the totals from the individual records received and compares them to the expected totals. If they don't match, an error has been detected.

    • Transaction counts--Use this method to keep track of the number of transactions that should have been processed by the application system.

Processing Controls
  1. There are two major types of processing controls:

    1. Run to Run

    2. File and Operator

  2. Run to run controls consist of data generation controls and verification controls.

    • Use data generation controls to ensure that the correct version of the file is being used.

    • Verification controls ensure that the totals or record counts for the prior run match the opening totals for the current run (e.g., header/trailer counts).

  3. File and operator controls are actions that the operator can take to insure that the application system is processing the right files and data. The controls can be as simple as checking a cartridge. Operator intervention should be kept to a minimum. Operator controls should be very specific and should be accompanied by sufficient operator instruction. For example, if the operator receives a message on the console: CARTRIDGE LABEL ERROR Enter "R" to retry, "N" to abort, " A" to accept. The operator should not be able to override this message.

Output Controls
  1. There are three types of output controls:

    1. Control Totals

    2. Verification Controls

    3. Distribution Controls

  2. Use control totals to verify the correctness of the outputs. For example, if an accounts payable application system generates 236 checks with an expected value of $395,000.12, the checks could be physically added to verify that the actual values of the checks were generated.

  3. Use verification controls to coordinate internal and external processes. For example, to avoid unauthorized loss of blank checks, have the computer keep track of the expected serial numbers of the preprinted checks and print the expected number on the check. If the two numbers differ, something is wrong.

  4. Use distribution controls to ensure that once an output is printed, it is delivered to the authorized recipients. This includes having users sign for reports on-site, as well as controls between sites.

External Data Controls
  1. External controls consist of that information necessary for operations personnel to perform balancing between and within runs. These controls are manual in nature and should include precise instructions as to:

    • Which output listing/file contains the control data;

    • What type of control data is being generated (e.g., transaction counts, hash totals, etc.);

    • How to balance the various elements of control data (e.g., ITEM 1 + ITEM 2 = ITEM 3).

  2. Accumulate and print controls at the end of processing to include, at a minimum:

    • Counts of total inputs and outputs;

    • Balancing counts;

    • Information counts;

    • Run to run counts; and to

    • generated, dropped and error records,

Control Totals
  1. Keep a record of the data as it moves through an application system and is subjected to a series of manual and automated processes. This can be accomplished in two ways:

    1. Controls Totals

    2. Control File

  2. Control totals can be embedded in the process itself. This is not the best approach since these totals are easily modified.

  3. A separate, highly controlled (limited user access) " control file" is very effective in that it is not as accessible as the data files. This file should include the following:

    • Block and/or record counts, hash totals, and total counts;

    • Logical record counts, if possible, when they differ from tape-record counts

    • Controls on money amount fields (cumulative arithmetic totals);

    • Adequate controls to account for all records, including those dropped, by-passed or combined during processing.

Intra-Run Controls
  1. Intra-run controls generate and/or present control information to operations personnel during the execution of the run.

  2. When designing a program, limit the amount of intervention required by operations personnel. As this is not always possible, consider the following ideas when developing intra-run controls:

    • Enable the run to print all operationally controlled parameters used for the run.

    • Stack all control data to a separate tape/disk file and print at the end of the job. Don't clutter the console with control information during processing.

    • Print totals for each run, every time, even when the totals are in balance.

Including Data Controls
  1. Include computer generated control lists with record counts by file, file number and name, money amounts and tape/disk numbers.

  2. Make sure that programs generate identifying information on all internally used output (e.g., reports). The project/run/file ID will be printed on each page of printed output. Do not print this information on transcripts, taxpayer letters and notices, and externally distributed reports.

  3. Include instructions for manually processing the control list.

  4. Computer generated cartridge numbers on all control lists:

    • Print cartridge file ID on controls page (from job number next to the corresponding count).

  5. Computer generated hard copy control output for all runs.

  6. List all control features in either the user handbook and/or the Computer Operators Handbook (COH), explaining:

    • The purpose and use of each control;

    • How they were derived and their meaning; and

    • The cause and meaning of all programmed halts.

  7. Assign a unique identifier to each cartridge file.

  8. When processing a multi-reel program that also has multi-file input, use halts at the end of each file if the accumulated counts are not equal to the record count in a trailer record.

  9. Institute checkpoint/restart capabilities for any application with estimated or actual run times that exceed one hour normal processing time as well as for large programs that process extensive amounts of data.

File Design and Cartridge Interface Formats

  1. This subsection addresses file design and cartridge interface format considerations.

File Design Formats
  1. The following sections include the design of the sequential file and logical data record formats. They are concerned with the association or grouping of the data elements into groups and records.

Record Format Design
  1. Fixed length records--a file composed of records that are all the same length.

  2. Variable-length records/multiple fixed formats--a file composed of a finite number of fixed length record sets, where the record lengths within any set are equal, but the record lengths between sets differ.

  3. Variable-length records/variable subscripted format--a file composed of one or more sets of records whose format consists of a fixed portion followed by a variable number of repeating groups. These groups must either be fixed in length, or composed of a fixed portion plus a subgroup whose entries are fixed in length.

  4. Variable-length records/variable string format--a file composed of records consisting of character strings of unspecified lengths.

Defining Data Fields
  1. When defining data fields which will compose a file, do not assign more than one significance to a field; (e.g., if a field is labeled DATE), the values carried by that field should be date information in all cases.

  2. Specify all the search key fields, and if possible, place them at the beginning of the record.

  3. Reduce redundant data fields to the minimum.

  4. Specify sensitivity levels for files. Classify all the sensitive data fields that require authorization for access.

  5. Restrict data fields to one and only one data item. This is really a VERY important standard to enforce

  6. The name should comply with IRM 2.5.7 Data Naming Standards to include characteristics such as a) the item should be easily defined. b) The name should reflect and be specific to what is in the field (e.g. IRS-Mailing-Dt.) c) Data names should end in a class word, indicating the data type.

  7. Data should not be intermixed (the same field should never be used for multiple types of data).

File Design
  1. Use "Fixed" and "variable multiple fixed" formats when possible.

  2. Avoid variable length records/variable subscripted format (i.e., Nth dimensional groups, where N is greater than 2).

  3. Do not use variable string formats.

Tape Interface
  1. Tape interface standards reduce the difficulty of sharing data between different users and different application systems. They allow the users to consider only the logical structure of files, and simplify the transporting and maintenance of data.

  2. All files created on an application system to be processed on another will:

    • Contain only ASCII character data;

    • Be in either Fixed or Variable format; and

    • Carry signs (+ or -) as a separate, leading ASCII character for signed numeric data fields. The reason for carrying signs separately is that ANSI otherwise leaves the method of signing as an implementor option; therefore, consistency of embedded signing between application systems should never be assumed.

  3. All files that are passed between application systems will be limited to 9995 characters per record.

  4. Record lengths (for variable records) consist of four decimal (ASCII) characters in the Record Control Word (RCW). The RCW is automatically generated by the application system and precedes each logical record.

Date Fields

  1. This subsection pertains to date fields and addresses the following topics:

    1. Year

    2. Date

    3. Gregorian Dates

    4. Exceptions

Year
  1. Format, output and represent all year fields as YYYY .

Date
  1. Do not store non-date values in DATE fields (i.e., indicators, freeze codes).

  2. Do not use any DATE field to store non-date information, as in the case of moving all 9's to a field as an indicator of a particular status.

  3. Do not store special characters in any DATE fields.

  4. Make DATE field names meaningful and accurately descriptive of the date stored in the fields, (e.g., BIRTH-DATE ).

  5. Add validity checks for DATE fields entered on screens or at their initial entry point into Service Application Systems. This includes External Trading Partners Processing.

  6. Externalize literal usage of dates wherever possible. For example, interest rates that apply to certain date ranges would be established as a data file or database table rather than being hard-coded in the program. If at all possible, eliminate hard-coded dates.

  7. Use system-wide standard DATE routines (either IRS-developed or COTS) in source code, wherever possible.

Gregorian Dates
  1. All Gregorian dates must be in (YYYYMMDD) format.

Exceptions
  1. Archive data no longer included in regularly scheduled processing need not be converted.

  2. Transmittal numbers and data set names (including File Names) containing dates need not be converted.

COBOL Programming

  1. This subsection provides establishes controls to ensure COBOL programs are reliable, maintainable, and portable.

Scope

  1. The controls prescribed are applicable to all IRS COBOL programs whether they are developed by the IRS or outside vendors for the IRS.

Basic Principles

  1. The development of structured COBOL programs in accordance with this section is dependent on structured design.

  2. Structured COBOL code is the implementation of the logic depicted in module specifications. Module specifications directly correspond to the modules shown on the structure chart.

  3. Structure charts, and therefore module specifications and structured code, are based on a top-down design of the application system. Each of the modules that constitute a structure chart should have a single entry point and a single exit point. The logic of each of the modules is based on various combinations of the three control structures: sequence, selection, and iteration.

  4. These principles have been established with the understanding that COBOL programs are not always maintained by the original author. All structured programs will have the same visual format. Only the most common formats are discussed.

Structured Programming

  1. Structured programming is comprised of three logical structures:

    1. sequence;

    2. selection; and

    3. iteration

  2. Sequence structure - In a sequential structure, the commands are executed in sequence. The flow of the program is to complete one instruction and then drop down and execute the next instruction and then the next until something terminates the sequence such as the end of a paragraph.

  3. Selection structure — In a selection structure the processing is dependent on a condition that is being tested. In COBOL, the selection structure is usually accomplished with an IF or an EVALUATE (the implementation of the case structure in COBOL) or with an implied IF such as the AT END clause in the READ statement.

  4. Iteration structure— (LOOP STRUCTURE) The iteration structure causes something to be executed over and over again until some condition terminates the repetition.

  5. This structure is essentially the looping structure that has been used in all of the programs.

  6. When defining iteration, there are two basic structures that a language may implement: Do-While and Do-Until.

  7. The difference between the two structures is when the condition is tested. In the Do-While structure the condition is tested before the loop is executed while in the Do-Until structure the condition is tested after the loop has been executed. This means that with the Do-While structure there is a possibility that the loop will never be executed.

  8. The PERFORM...UNTIL used in the sample programs is an example of the Do-While structure because the condition is tested before the loop is executed.

  9. Use meaningful names. Ensure names conform to IRM 2.5.7 Data Naming Standards.

General Programming
  1. This section applies to all divisions of a COBOL program.

  2. COBOL programs shall be written in accordance with the American National Standard Institute (ANSI). Where a standard is not specified in this manual, the relevant ANSI standard will be considered the established standard.

  3. Begin to insert comment line in these specified areas:

    1. IDENTIFICATION DIVISION

    2. DATA DIVISION

    3. WORKING-STORAGE SECTION

    4. LINKAGE SECTION

    5. PROCEDURE DIVISION

    6. Any section within the PROCEDURE DIVISION.

    7. Any paragraph/section that represents a Structure Chart module within the PROCEDURE DIVISION.

  4. Place division, section, and paragraph names on a line by themselves and start in column 8. This also applies to the module names corresponding to structure chart modules.

  5. Insert a blank line between each Division name and the first statement of the Division.

  6. Insert a blank line between each Section name and the first statement of the Section.

  7. Do not split names or words between lines. If possible, avoid splitting literals between lines.

  8. Only one statement per line is allowed.

  9. With the exception of nested IF constructs, end each statement with a period.

  10. Indent statements that are continued on another line at least two spaces from the starting position of the initial line.

  11. Use blank lines and page ejects effectively.

  12. Use meaningful names. Ensure names conform to IRM 2.5.7 Data Naming Standards.

Identification Division
  1. Include the following paragraphs in the IDENTIFICATION DIVISION of all programs: AUTHOR, INSTALLATION, SECURITY, and REMARKS. When necessary, they will be annotated as COBOL comments.

  2. The AUTHOR paragraph will include:

    • The name and office symbols of the section(s) responsible for the maintenance of the program.

    • At a minimum, the name of the last programmer/analyst to write or modify any of the code of the program.

    • It is a good practice to retain the names of the last few authors to allow quicker access to originators of code if problems arise.

  3. The INSTALLATION paragraph will contain " INTERNAL REVENUE SERVICE" .

  4. The SECURITY paragraph will contain " FOR OFFICIAL USE ONLY" .

  5. REMARKS paragraph will describe the function of the program, the subprograms that are called, the files that are used by the program, and the effective date. At the developer's option, this paragraph may also list modified modules and reasons for modifications after the program has been in production. (This often leads to quicker resolution of problems.)

Environment Division
  1. Start each main clause (for example, the SELECT clause) in column 12.

  2. Start each sub-clause in column 16.

Data Division
  1. Start FD and 01 entries start in column 8. Clauses of FD entries will start in column 12, one clause per line.

  2. Put level numbers in sequential order to reflect the logical levels of the structure (i.e., 01, 02, 03 rather than 01, 05, 10, 15, etc.).

  3. Indent level numbers 4 positions for each subordinate level.

  4. Indent data names (including condition names) 2 columns to the right of the level number. For example, see the following figure.

    Figure 2.5.3-1

    02 NO-MORE-MASTERS-FLAG PIC X(5)
    88 NO-MORE-MASTERS VALUE " TRUE" .
    88 MORE-MASTERS VALUE " FALSE" .

  5. Do not use 77 level entries in the DATA DIVISION.

  6. Start all PIC, VALUE, USAGE, OCCURS, and REDEFINES clauses in the same column, where possible.

  7. PIC clauses must not contain sequences of more than two identical symbols (except for edited fields). For example, use PIC X(4) rather than PIC XXXX. An edited field such as PIC ZZ,ZZZ.99 will be allowed.

  8. Do not group program flags, indexes, constants, etc., by class, under one 01 level. For example, in the following figure, the code would be prohibited.

    Figure 2.5.3-2

    01 PROGRAM-FLAGS
    02 NO-MORE-MASTERS-FLAG
    02 MORE-UPDATES-FLAG

  9. Ensure that local variables and constants associated with one module immediately follow each other in the DATA DIVISION. If a variable or constant is associated with more than one module, it should usually be defined with the highest level module that references it.

  10. Do not give flags and indexes multiple uses.

  11. Initialize constants, variables and output record areas by using the initialize statement or as follows:

    • Initialize constants in working storage, including FILLER fields, with a VALUE clause. Use VALUE SPACES or ZEROS, not "b" or "0" .

    • Initialize the variables in working storage (i.e., those fields that are changed during execution of the program) by using specific statements in the PROCEDURE DIVISION.

    • Initialize output record areas to clear buffers that are not overlaid during program execution. One way to initialize an output record area is to move SPACES to the record as a group item, and then move ZEROS to the numeric fields.

  12. Use meaningful data names derived from the problem being solved. Where applicable, data names should be consistent with those used in the structure charts. COBOL allows names of up to 30 characters. Ensure that names conform with IRM 2.5.7 Data Naming Standards.

  13. Avoid data names that convey little meaning. For example, see the following figure.

    Figure 2.5.3-3

    INDEX, I, K, TR127, COUNTER, EOT.

  14. Use data names that convey meaning. For example, see the following figure.

    Figure 2.5.3-4

    MESSAGE-INDEX
    TRANSACTION-COUNT
    NO-MORE-TRANSACTIONS-FLAG

  15. Apply the PIC 9 versus PIC X standard to date fields in the following manner:

    • Use PIC 9 for date fields in situations where the particular date value in question will be used for numeric functions (e.g., calculations, computations, estimations, etc.) rather than for accepting input or direct display. Assign four positions to the year field (YYYY) and do not store non-date values or special characters in the date field.

    • Define the data as necessary (PIC X, PIC 9, PIC S9, or another format) in order to accommodate input that may be blank, coming from electronic files, External Trading Partners (e.g., SSA), taxpayer submitted files, DB2 special formats, unique database machine formats, or other formats. It is not necessary to use PIC 9 when defining fields that are accepting input.

    • Define the data as necessary (PIC X, PIC 9, PIC S9, or another format) in order to display data (e.g., reports, screens) or format/unformat display dates that contain special characters in edit fields (e.g., slashes, commas, dashes, etc., depending on the function requested). However, note that the Year Field must be four positions (YYYY). It is not necessary to use PIC 9 when displaying data.

Procedure Division
  1. A functional module should be limited to 50 lines of executable code as a general rule.

  2. Each module (not each paragraph within a module) must start on a new page with comment lines indicating the module number of the Structure Chart that is represented by the code and the function of the module as described on the Module Specification. For example, see the following figure.

    Figure 2.5.3-5

    /** MODULE 2.4.3.7
    *
    * (Description of module)
    *
    * GET-VALID-TRANSACTION.
    READ TRANSACTION-FILE
    AT END
    MOVE "TRUE" TO NO-MORE-TRANSACTIONS-FLAG.
    --rest of code--

  3. Module names in a COBOL listing must correspond to Structure Chart module names.

  4. Name a paragraph that is an implementation of an N-S control structure (e.g., PERFORM-UNTIL, ELSE, CASE, nested IF-THEN-DO-UNTIL, etc.) in a way that explains its purpose. These paragraphs are not separate modules; they are paragraphs within the module.

  5. Arrange modules in a program listing in either a horizontal or a vertical sequence corresponding to the Structure Chart level numbers. For example, see the following figure.

    Figure 2.5.3-6

    Horizontal Module Arrangement --Veritical Module Arrangement
    0.0 0.0
    1.0 1.0
    2.0 1.1
    3.0 1.2
    1.1 2.0
    1.2 2.1
    2.1 2.1.1
    2.2 2.1.2
    2.3 2.1.2.1
    2.1.1 2.1.2.2
    2.1.2 2.1.3
    2.1.3 2.2
    2.2.1 2.2.1
    2.2.2 2.2.2
    2.1.2.1 2.3
    2.1.2.2 3.0
    etc. etc.

  6. Code the READ statement and WRITE statement options one per line, indented 2 columns. See the following figure.

    Figure 2.5.3-7

    READ file-name WRITE record-name
    AT END AFTER ADVANCING identifier LINES
    statements. statement.
    or, or,
    READ file-name WRITE record-name
    INVALID-KEY INVALID-KEY
    statements. statement.

  7. Place phrases such as AT END, WHEN, and VARYING on the next line indented two columns.

  8. Begin any statement not covered by other indentation rules in the same column as the statement above it.

  9. Never use the ALTER verb (or any other method of dynamically altering thePROCEDURE DIVISION).

  10. Do not use the GO TO verb, except in the implementation of the CASE construct or in the use of internal SORT exits.

  11. Handle all file openings and closings in any given module with one OPEN or CLOSE statement. The following figure depicts these formats.

    Figure 2.5.3-8

    OPEN INPUT file-name-1
    file-name-2
    OUTPUT file-name-3
    file-name-4
    CLOSE file-name-1
    file-name-2

  12. Immediately follow the MOVE CORRESPONDING statement with a comment documenting all data items involved. This ensures thorough documentation. For example, see the following figure.

    Figure 2.5.3-9

    MOVE CORRESPONDING RECORD-A TO RECORD-B
    *FIELD-1, FIELD-3, FIELD-5.

  13. Use the COMPUTE verb to develop Arithmetic operations with the following exceptions:

    • Use the DIVIDE statement to compute remainders.

    • ADD X to (counter) and SUBTRACT X from (counter) are allowed.

  14. STOP RUN must only occur once as the last logical statement in the main procedure of a program. EXIT PROGRAM may only occur as the last logical statement of the main procedure of a subprogram. EXCEPTION: In some cases, it may be justifiable to use a STOP RUN in a low-level module of a very large run.

  15. Make the logic of the program independent of the physical sequence of paragraphs. A PERFORM statement should not perform more than one paragraph within a PERFORM statement. Explicitly identify paragraphs. For example, two figures follow. The first figure illustrates a statement that would not satisfy this standard. The second figure illustrates a statement that satisfies this standard.

    Figure 2.5.3-10

    PERFORM Paragraph-A THRU Paragraph-B.

    Figure 2.5.3-11

    PERFORM Paragraph-A.
    PERFORM Paragraph-B.

  16. The following figure illustrates a statement that is exempt from this standard.

    Figure 2.5.3-12

    PERFORM Case-Paragraph
    THRU Case-End-Paragraph.

  17. When a module is invoked via a PERFORM statement, represent the parameter table shown on the Structure Chart with comment lines. In the following figure, Parm-3 is both input to and output from Module-X.

    Figure 2.5.3-13

    PERFORM MODULE-X.
    * ** USING: Parm-1,Parm-2,Parm-3
    * ** GIVING: Parm-3,Parm-4,Parm-5

  18. When a module is invoked via a CALL statement, do not list the USING phrase as a comment line as it is part of the syntax. Group all parameters shown on the Structure Chart Diagram that are passed between the main program and the called module so that all of the input parameters precede the output parameters. Represent the GIVING phrase as a comment line and identify the output parameters (since COBOL does not make the distinction between input and output parameters). In the following example Parm-1 through Parm-5 are listed in the USING phrase, but not as a comment line. Any output parameter that is input to the module, such as Parm-3 illustrated in the following figure, is listed in the GIVING as a comment (so that it is not listed twice in the program code).

    Figure 2.5.3-14

    CALL Module-X
    USING Parm-1,Parm-2,Parm-3
    * ** GIVING Parm-3,
    Parm-4,Parm-5.

  19. The PERFORM verb has 5 acceptable formats:

    • PERFORM Paragraph-Name.--This format is used with USING and GIVING comment statements to implement a module call; or used without the comments to PERFORM paragraphs within a module. (e.g., nested IFs, the body of the (PERFORM-UNTIL) structure, etc.).

    • PERFORM Select-Case THRU Select-Case-End.--The THRU option of the PERFORM should only be used for implementation of the SELECT-CASE structure.

    • PERFORM Paragraph-Name UNTIL Terminating--Condition.

    • PERFORM Line-Spacing-Paragraph Line-Count TIMES.--This option executes a procedure a set number of times.

    • The PERFORM-UNTIL may also be used to vary a subscript or index as in a table-search routine. See the following figure.

    Figure 2.5.3-15

    PERFORM Table-Search
    VARYING Table-Index
    FROM 1 BY 1
    UNTIL Match-Found
    OR Table-Index GREATER THAN Max-Entries.

  20. Implement the DO-UNTIL structure in one of two ways. The first way is a PERFORM/PERFORM-UNTIL combination. See the following figure.

    Figure 2.5.3-16

    PERFORM Paragraph-Name.
    PERFORM Paragraph-Name
    UNTIL Terminating-Condition.

  21. The second way to implement a DO-UNTIL structure is to use a switch to terminate the loop. See the following figure.

    Figure 2.5.3-17

    MOVE True to Loop-Predicate.
    PERFORM Paragraph-Name
    UNTIL Loop-Predicate = False.
    ...
    Paragraph-Name.
    . . . Statements . . .
    IF Terminating-Condition
    * THEN
    Move False to Loop-Predicate.
    * END-IF

  22. The following figure illustrates the format of the IF-THEN-ELSE statement.

    Figure 2.5.3-18

    IF Condition
    * THEN
    True-Procedures
    ELSE
    False-Procedures.
    * END-IF

  23. The ELSE part of the IF statement is optional when there are no actions to be taken (i.e., "ELSE NEXT SENTENCE" is not required). The THEN and END-IF comments are required. The True-Procedure and False-Procedure statements are indented 2 spaces from their corresponding THEN or ELSE. The IF and the corresponding END-IF keywords start in the same column. The THEN and ELSE keywords are indented 2 spaces in from the IF. As a guideline, the positive condition (rather than the negative) should be tested in a conditional statement. In a compound conditional statement, negative and positive tests should not be mixed.

  24. When there are compound conditions associated with an IF statement, ensure that the statement is as readable as possible. The best method of doing this depends on the particular condition. The following figures illustrate the two formats.

    Figure 2.5.3-19

    Format 1 – Putting each condition on a separate line:
    IF Condition-1
    OR Condition-2
    * THEN
    True-Procedures
    ELSE
    False-Procedures.
    * END-IF

    Figure 2.5.3-20

    Format 2 – Using parentheses to specify the order of evaluation for the individual conditions of more complex conditions:
    IF ((Condition-1) OR (Condition-2))
    AND Condition-3
    * THEN
    True-Procedures
    ELSE
    False-Procedures.
    * END-IF

  25. Do not nest IF statements more than 3 levels deep. See the following figure.

    Figure 2.5.3-21

    * THEN
    IF Condition-2
    AND Condition-3
    * THEN
    True-Procedure-1
    ELSE
    False-Procedure-1
    * END-IF
    ELSE
    False-Procedure-2.
    * END-IF

  26. If it appears that the nesting has to be more than 3 levels deep or even if the statement looks "cluttered" at 2 or 3 levels then PERFORM the inner test conditions. See the following figure.

    Figure 2.5.3-22

    IF Condition-1
    * THEN
    PERFORM Inner-Test
    ELSE
    False-Procedure-2.
    * END-IF
    .
    .
    Inner-Test.
    IF Condition-2
    AND
    * Condition-3
    * THEN
    True-Procedure-1
    ELSE
    False-Procedure-1.
    * END-IF

  27. Implement the SELECT-CASE construct in one of two ways:

    1. Nested IFs

    2. GO TO DEPENDING ON

  28. Implement the "Nested IF" of the SELECT-CASE construct as prescribed in the following figure. Note that this format is different from a normal IF-THEN-ELSE statement.

    Figure 2.5.3-23

    * SELECT CASE.
    IF Condition-1
    * CASE-1:
    Case-1-Statements
    ELSE
    IF Condition-2
    * CASE-2:
    Case-2-Statements
    ELSE
    IF Condition-3
    * CASE-3:
    Case-3-Statements
    ELSE
    * Error-CASE:
    Error-Case-Statements.
    * ENDCASE

  29. Implement the GO TO DEPENDING ON of the SELECT-CASE as prescribed in the following figure. Note that the ERROR-CASE statement comes before the valid case paragraphs. Each case has a separate paragraph with a GO TO the EXIT paragraph. This structure is normally executed via a PERFORM Select-Case THRU Select-Case-End statement.

    Figure 2.5.3-24

    SELECT CASE
    GO TO
    CASE-1
    CASE-2
    .
    .
    .
    CASE-N
    DEPENDING ON Select-Code.
    ERROR-CASE.
    Error-Statements.
    GO TO SELECT-CASE-END.
    CASE-1.
    Case-1-Statements.
    GO TO SELECT-CASE-END.
    CASE-2.
    Case-2-Statements.
    GO TO SELECT-CASE-END.
    ...
    CASE-N.
    Case-n-Statements.
    GO TO SELECT-CASE-END.
    SELECT-CASE-END.
    EXIT.

C Programming

  1. This section of the IRM provides guidelines for coding C programs and naming C program components.

File Naming

  1. Create the file names from a base name and an optional period and suffix.

  2. Store very large files by date (for archive or delete). Make the date a part of the name (e.g. log files).

  3. Make the first character of the name a letter.

  4. Assign a file name that is unique in as large a context as possible.

  5. Use uppercase and lowercase letters to name source code files.

  6. Include comments in the module so other programmers will understand the modules' purpose (ie., Title Section).

  7. Use System Name followed by file name. For example, the application system is Telefile (or EMS, TEPS, EFDS, EFTPS, etc.) and the file name is ReturnData.

  8. Include comments on the name

  9. Generally, programs that rely heavily on external libraries, such as GUI programs written using X/Motif, are constrained by the naming conventions employed by these libraries.

Source Code Files

  1. Size Considerations:

    1. Limit the size of a source code file to 1000 lines as large source code files can be very cumbersome to deal with.

    2. Per each line in a source code file, limit the number of characters per line to 163 or fewer characters.

    3. Decompose long lines into smaller pieces, such that when the file is printed, all portions of the code will print out legibly.

    4. Indent subsequent sections of a longer line so that it is clear that these are continuations of the line above.

    5. In the length of a line, include any commentary that follows the code on the line.

    6. Where a function exceeds two pages, reexamine the design of the function.

    7. Especially consider if more than one function is involved or if sub-functions would be better in separate modules.

    8. If functions are short and related to each other, then place them in same source code file.

  2. Composition:

    1. Prologue

    2. Includes

    3. Defines and Typedefs

    4. Global Definitions

    5. Function Placement

Prologue
  1. Make the prologue first in the file as it indicates what is in that file.

  2. Use a description of the purpose of the objects in the files (whether they be functions, external data declarations or definitions or something else) rather than a list of the object names. A description of the method(s) used is helpful for any complex function.

  3. Avoid making descriptions so detailed that maintenance of the header takes more effort than is gained by increased understanding of the code itself.

Includes
  1. Header files are files that are included in other files prior to compilation by the C preprocessor.

  2. Place the header file after the prologue. If the include is for a non-obvious reason, comment the reason. In most cases, application system include files like stdio.h should be included before user include files.

Header File Organization
  1. Relate all functions in a given header file to the same general function, i.e. declarations for separate sub-systems should be in separate header files. Example: all functions in the header file stdio.h either perform or assist in the performance of input and output.

  2. Do not use any function implementations, except macros in Header files.

  3. Within a header file, group functions that perform related tasks in the same section. Example: within the file stdio.h, all functions in the scanf family must be placed together.

  4. Define and include certain header files, such as stdio.h at the application system level and for any program using the standard I/O library.

  5. Use Header files to contain data declarations and defines that are needed by more than one program.

  6. Organize header files functionally, i.e., declarations for separate subsystems should be in separate header files.

  7. If a set of declarations is likely to change when code is ported from one machine to another, place those declarations in a separate header file.

  8. Use "><" (>stdio.h<) for system include files and double quotes ("user.h" ) for user include files.

Header File Inclusion in the File that defines the Function
  1. Include Header files that declare functions or external variables in the file that defines the function or variable. This allows the compiler to do type checking and the external declaration will always agree with the definition.

  2. To prevent accidental double-inclusion, in each .h file, use code like the following.

    #ifndef EXAMPLE:
    #define EXAMPLE
    ... /* body of example.h file */
    #end-if /* EXAMPLE */

  3. Use a general-purpose header file for commonly used symbolic constants.

Nested Header Files
  1. Do not nest Header files. The prologue for a header file must describe what other headers need to be included for the header to be functional.

  2. Where a large number of header files are to be included in several different source files, put all common include statements in one include file.

Header File Names
  1. Avoid private header filenames that are the same as public header filenames. The statement #include "math.h" must include the standard library math header file if the intended one is not found in the current directory. If this is what you want to happen, comment this fact.

  2. Don't use absolute pathnames for header files. Use the >name< construction for getting them from a standard place, or define them relative to the current directory. Use the "include-path" option of the C compiler (-I on many application systems) used in the Makefile to handle extensive private libraries of header files; it permits reorganizing the directory structure without having to alter source files.

Defines and Typedefs
  1. Place the defines and typedefs that apply to the file as a whole after the includes.

  2. It is sometimes useful to place a Define before the header files so that they will apply to the header files.

  3. Place "constant'" macros first, then " function" ' macros, then typedefs and enums.

Global Definitions
  1. Place the global (external) data declarations after the Defines/ Typedefs.

  2. Use the order: externs, non-static globals, static globals

  3. If a set of defines applies to a particular piece of global data (such as a flags word), place the defines immediately after the data declaration or embedded in structure declarations, indented to put the defines one level deeper than the first keyword of the declaration to which they apply.

Function Placement
  1. Place the functions last.

  2. Place like functions together.

  3. Use a "breadth-first" approach (functions on a similar level of abstraction together) rather than depth-first (functions defined as soon as possible before or after their calls).

  4. If defining large numbers of essentially independent utility functions, consider alphabetical order.

Other Files

  1. For operator-directed programs, establish a file called " Readme" to document both the file and issues for the program or a group of programs. For example, it is common to include a list of all conditional compilation flags and what they mean.

  2. List files that are machine dependent, etc.

Global Variable Declarations

  1. The following subsections address global variable and structure declarations.

Global Variables
  1. Avoid the use of global variables unless you have cases where the use of global variables can actually make a program more readable by not cluttering function calls.

  2. Declare any global variables at the top of a file, before any function declarations.

  3. Declare variables, which are global to only the functions in a single file, as "static" .

  4. Use meaningful names (MaxLength=30 characters).

  5. Separate the words of a compound variable by capitalizing the first letter of every word.

  6. Start pointer names with "p" .

  7. Separate unrelated declarations, even of the same type, on separate lines.

  8. Tab the names, values, and comments so that they line up. See the following table.

    int EventInit; /* event_init performed */
    char TaxFormType; /* type of the tax return form /
    char *pFirstEntry; /* ptr to 1st entry */

Structure Declaration
  1. Declare each field in a structure on a separate line.

  2. If you declare a local structure – use lower case for the names. If you declare a global structure – use mixed case for the names. The variables that comprise the structure (structure elements) must follow the same rule as local or global variables

  3. Assign a structure to a variable in a separate statement.

  4. Recommended Styles:

    1. The following table illustrates a style where the opening brace ({) should be in column 1 on a next line after the structure tag, and the closing brace (}) should be in column 1.

    struct ECT_REG_HEADER_S
    {
    char *pFirstEntry; /* ptr to 1st registry entry */
    int NumEntries; /* number of entries */
    }

    2) The following table illustrates a style where the opening brace ({) should be on the same line as the structure tag, and the closing brace (}) should be in column 1. Choose one of these styles for the opening brace ({) and consistently use it.

    struct ECT_REG_HEADER_S {
    char *pFirstEntry; /* ptr to 1st registry entry */
    int NumEntries; /* number of entries */
    }

Typedef Declaration
  1. Structures may be typedeffed when they are declared.

Local Variable Declarations

  1. Do not use names with leading and trailing underscores for any user-created names as they are reserved for application system purposes. Most application systems use them for names that the user should not have to know.

Local Variable Names
  1. The following paragraphs cite guidelines.

  2. Declare local variables at the start of, or just before, the block in which they are used. If the variable name is going to be reused in a different block in the same function then declare the variable at the start of the function.

  3. Do not have a function contain two variables with the same name.

  4. Avoid declaring variables within any block, (e.g., within a " for" block).

  5. Use meaningful names (max_length=30 characters).

  6. Begin all variable names with a lowercase letter.

  7. Place the pointer qualifier, * with the variable name rather than with the type.

  8. Separate unrelated declarations, even of the same type, on separate lines.

  9. Include a comment describing the variable in the same line.

  10. Tab the names, values, and comments so that they line up. An example follows.

    int event_init; /* event_init performed */
    Char tax_form_type; /* type of the tax return form */
    Char *first_entry_p; /* ptr to 1st entry */

Typedef Declaration
  1. Give the struct and typedef the same name. Apply the same rules as for a structure declaration.

Abbreviations for Common Variable
  1. Use conventional abbreviations for common variables.

    average avg
    database db
    Length len
    message msg
    number num
    position pos
    String str

Constants

  1. This subsection addresses constants and enumeration data.

Defining Constants
  1. Avoid coding numerical constants directly. But, a numerical constant that affects and is used throughout the whole program should be declared to facilitate changes, but actual numbers could be used in small scope code.

  2. Use symbolic constants to make the code easier to read.

  3. Define the value in one place to make it easier to administer large programs since the constant value can be changed uniformly by changing only the define.

Consistency of Constant Definitions
  1. Consistently define constants with their use, (e.g. use 540.0 for a double instead of 540 with an implicit float cast).

Conventional Constants
  1. Use a conventional set of symbolic constants for constants common to C coding:

    TRUE commonly defined by system supplier headers. Do not redefine.
    FALSE commonly defined by system supplier headers. Do not redefine.
    #define FALSE 0 commonly defined by system supplier headers. Do not redefine.
    #define TRUE !FALSE commonly defined by system supplier headers. Do not redefine.
    LF_CHAR line feed character
    CR_CHAR carriage return character
    EOS end of string character
    EOF commonly defined by system supplier headers. Do not redefine.

Enumeration Data
  1. Use the enumeration data type to declare variables that take on only a discrete set of values, since additional type checking is often available.

  2. Declare each field in a enum on a separate line.

  3. Ensure the enum type name has a tag, in upper case with " _E" appended to their name

  4. Ensure each field in an enum type is in upper case separated by underscores.

    enum ACMW_E
    {
    ACMW_IB_TP_INTERFACE = 5001,
    ACMW_IB_USER_VALIDATION = 5002
    }

Symbolic Constants - #define
  1. Name all quantities that must remain unchanged throughout a program using the "#define" capability. The defined name must be in upper case letters.

    #define FEP_FAILURE "FEP ACKNOWLEDGMENT_FAILURE"
    #define AT_AUDIT_NAME "7"

Functions

  1. This subsection addresses:

    1. return values

    2. parameter lists

    3. function body

    4. function prototype

    5. function naming

Return Values
  1. Explicitly declare all return values.

  2. Do not default to int; if the function does not return a value then give it return type void.

  3. If the value returned requires a long explanation, give it in the prologue.

Parameter Lists
  1. If the function and its parameter list is longer than one line, indent lines after the first one from the left margin so that the second line of the parameter list starts directly below where the parameter list begins on the first line.

  2. Ensure a function that returns information via one or more of its parameters only returns status information in its name.

  3. Ensure each parameter passed to a function occurs on a separate line in the function prologue with a short comment describing its function.

Function Body
  1. Tab all local variable declarations and code within the body over one stop.

  2. Place the opening brace, "{" , opening the body of the function on a line by itself and left justified or at the end of the line which introduces the block. Any control statements will cause further indentation from this basic indentation.

  3. If the function uses any external variables (or functions) that are not declared globally in the file, provide the declarations in the function body using the extern keyword.

  4. Avoid local declarations that override declarations at higher levels.

  5. Redeclare local variables in nested blocks.

  6. Ensure that a single return statement is always present with a parameter if the function is not of type void. Use one even if the function has no return value and, therefore the C language does not require a return. This can be useful for setting a break point during debugging.

  7. Place a closing brace, "}" , closing the body of the function, on a line by itself and left justified.

Function Prototype
  1. Generate Function Prototype for all functions generated.

Function Naming
  1. Select a naming convention (capitalization, underscores, etc.) and use it consistently.

  2. For naming services:

    • Limit service name to 12 characters. Longer names, when accepted, by Tuxedo, will be truncated to 12 characters.

    • Begin all service names with an uppercase letter.

    • Separate the words of compound service names by capitalizing the first letter of every word.

Comments

  1. Use comments in your programs to meet the following three (3) goals:

    1. Clear and concise

    2. Place where needed

    3. Useful to read the code

  2. Strive to balance the amount of comments with the amount of whitespace to maintain readability and clarity.

  3. Make sure the comments describe what is happening, how it is being done, what parameters mean, which globals are used and which are modified, and any restrictions or bugs.

  4. Avoid comments that are clear from the code. Such information rapidly gets out of date, is redundant and clutters the code.

Template for File and Header
  1. Place the following header at the beginning of the file:

    /*********************************************************************
    //
    // Internal Revenue Service
    // For Official Use Only
    //
    //
    // Filename: Filename
    // Description: Describe the purpose of the objects in the file,
    // followed, in the case of source files, by a list of
    // functions whose definitions appear in the file
    // Related Files: An identification of any routines or files that this
    // file may require
    // Restrictions/ Known special cases where the file may not work
    // Problems:
    //
    // Date Modified: Date: YYYY/MM/DD
    // Version id: Revision:
    // Author: Author: >First Name< >Last Name<
    // Locked by: $Locker: $
    //
    // Revision History: To clearly identify all the changes, when doing code reviews, print out the information. Look at ClearCase to identify the revision date. If enough information is there, look at the header for specifics. Not putting it in the code reduces your options to hoping the clearcase information is sufficient, and doing a line-by-line review in clearcase until you find the change.

  2. Place the following header at the beginning of the function:

    /********************************************************************
    * Function Name:
    * Description: A description of the major task(s) performed by
    * routine. It should be a series of one or more simple
    * verb/object statements
    * Input parameters:
    * Output parameters
    ********************************************************************/

Function Comments
  1. Place comments that describe data structures, algorithms, etc., in block comment form.

  2. Present code in paragraph form prior to a block of code.

  3. Use comments for cohesive blocks of code when they explain the purpose of the block in accomplishing a cohesive task. This enables the reader to understand the function being implemented. Thus the reader will be able to quickly find the appropriate section of code without getting bogged down in coding details for other sections of code. For example:

    /*********************************************************
    * LOCAL VARIABLES and CONSTANTS *
    **********************************************************/
    /**********************************************************
    * cleanup_pipeline PROCESSING *
    **********************************************************/

  4. Indent block comments to the same level as the block being described.

  5. Indent one-line comments alone on a line to the tab setting of the code that follows. For example:

    if (argc < 1)
    {
    /* Get input file from command line. */
    if (freopen(argv[1], "r " , stdin) == NULL)
    {
    perror (argv[1]);
    }
    }

  6. Very short comments may appear on the same line as the code they describe, but must be tabbed over to separate them from the statements.

  7. If more than one short comment appears in a block of code they must be tabbed to the same tab setting. For example:

    if (a == EXCEPTION)
    {
    b = TRUE; /* special case */
    }
    else
    {
    b = isprime(a); /* works only for odd a */
    }

Statements

  1. This subsection addresses the following topics related to statements:

    1. Statements per Line

    2. Single Statement Blocks

    3. Multiple Statement Blocks

    4. Levels of Control Structure Nesting

    5. Goto Statement

    6. Break Statement

    7. Null Statement

    8. Conditional Statement

    9. Exit Statement

    10. Default Truth Value

    11. Increment and Decrement Operators

    12. Added Statements for Debugging

Statements per Line
  1. Generally, source code should depict one statement per line.

Single Statement Blocks
  1. Block off even a single statement following a "while" , "if" , "else" , etc.

  2. Using the curly braces "{}" is required only when there is a block of more than one statement. However, putting in the braces makes the scope of the control statement very clear and helps to protect the code in the event that a second line is added to the block if the single line contains a macro, which translates into more than one line of code.

    if (SomeCondition == TRUE)
    {
    ThisVariable = SomeVariable;
    }

Multiple Statement Blocks
  1. Statements that affect a block of code (i.e., more than one statement) must either have the opening brace "{" at the end of the line containing the control statement, or the opening brace must be on the line immediately below and lined up with the first letter of the control statement.

  2. Indent the body of the block one step from the control statement.

  3. Place the ending brace, "}" on a line by itself and at the same indentation level as the control statement.

  4. Choose one of the two styles and use it consistently:

    1st Style:
    If (condition)
    {
    statements(s)
    }
    else
    if (condition)
    {
    statements(s)
    }
    for (loop control expressions)
    {
    statements(s)
    }
    while (condition)
    {
    statements(s)
    }
    switch (expression)
    {
    case constant1;
    statement(s)
    case constant2;
    statement(s)
    default;
    statement(s)
    }

    2nd Style:
    if (condition) {
    statement(s)
    } else if (condition) {
    statement(s)
    }
    for (loop control expressions) {
    statement(s)
    }
    while *condition) {
    statement(s)
    }
    switch (expression) {
    case constant1;
    statement(s)
    case constant2;
    statement(s)
    default;
    statement(s)
    }

Levels of Control Structure Nesting
  1. Do not nest conditional statements, such as "while" , "if" , "else" , more than 4 levels. If more levels are required, consider using a function at one of the higher levels.

Goto Statement
  1. Do not use the Goto statement.

Break Statement
  1. If a particular case in a switch statement is meant to drop through to the next case (i.e., it has the same effect), the fact that the earlier case has no "break" statement must be explicitly noted with a comment. For example:

    switch(switch_form)
    {
    case P1040 : /* same action as for 1065; no break */
    case P1065:
    process_1040();
    break;
    default : /* if not 1040 or 1065, no action taken */
    break;
    }

Null Statement
  1. Generally, Null statements should include a comment line.

  2. Place the null body of a "for" or " while" loop alone on a line and commented so that it is clear that the null body is intentional and not missing code.

    while (*dest++ = *src++)
    ; /* VOID */

Conditional Statement
  1. Break out the function call onto a separate line followed by a new line containing the conditional statement. Often a program will branch based on the success or failure of a function call. Consider the following excerpts of source code, the first excerpt is easier to understand than the second excerpt.

    pFileHandle = fopen("some_file " , READ_ONLY);
    if (pFileHandle == NULL)
    {
    printf("Could not open file; program terminating." );
    TerminateApplication();
    }
    else
    {
    DoSomething();
    }

    if ((pFileHandle = open(" some_file" , READ_ONLY))== NULL)
    {
    printf("Could not open file; program terminating." );
    TerminateApplication();
    }
    Else
    {
    DoSomething();
    }

  2. The preceding "fopen" example demonstrates a style, which helps to avoid internal side effects. "Side effect" as used in this example refers to the fact that the reader may focus on the "if (xxx == NULL)" aspect of the statement and not fully realize that there is a call to "fopen()" . The other danger of this type of compound statement is the potential for completely changing the meaning if the parentheses around the"pFileHandle = open()" part are left off.

Exit Statement
  1. Except for use in error-handling functions, avoid explicit use of the "exit();" statement.

Default Truth Value
  1. Use explicit comparison even if the comparison value will never change.

Added Statments for Debugging
  1. If you include statements to print out information during debugging, use preprocessor switch(es) in the makefile to allow compile-time control of the debug output, and use #ifdef statements to control inclusion of the debug statements. For example:

    #ifdef DEBUG_1
    printf(some debug statement);
    Fprint(>pointer to FML buffer<);
    #end-if

Operators

  1. Do not use the ternary conditional operator, "?:" in the main program, primarily to make the code more readable. It can still be used in macros.

  2. An increment or decrement operation should be explicitly placed in a separate statement so it would be clear what is occurring and when.

  3. Ensure that all operators which take two parameters have a single space on either side of the operator. This makes it very handy to use an editor to search for a variable assignment; you need only search for " a =" and not "a =" as well as "a= " . It also makes the code more readable.

  4. In contrast to binary operators, ensure that all unary operators (e.g., a minus sign or the address operator, "&" ) have no space between the operator and the object.

  5. Where operator precedence must be known to determine the meaning of an expression, use parentheses to eliminate any ambiguity, which might arise from lack of knowledge of operator precedence. For example, to increment the variable pointed to by the pointer "pNumTimes" , use "(*pNumTimes)++" . This use of parentheses makes it clear that the contents of location "pNumTimes" is being incremented and not the address itself.

  6. The ternary conditional operator may be useful in parameter lists and as a return value.

ESQL/C

  1. This subsection addresses:

    1. Database Error Checks

    2. Operations

    3. Performance

    4. SQL Statements

Database Error Checks
  1. Ensure that all calls to the database have error checking.

  2. If a cursor is used, place an error check immediately after the declare, open, all fetches, and close cursor.

  3. If a data retrieval error occurs, end the data retrieval processing and the variable that holds the unretrieved data will be populated with the default value for missing data as per the application program guidelines. A NULL value is not acceptable.

Operations
  1. Due to the constraint that not more than one database can be open at a time, always check to see if a database is open before there is a call to open one.

  2. Before any program exits, close the open database.

  3. Declare cursors in the same function they are used.

  4. Close and free cursors after they are used.

  5. If a SQL error occurs, log the message to display the sql code, the function name, the file name, and the error message.

Performance
  1. Minimize overhead processing and optimize memory allocations.

  2. Do not pass more than one variable or structure to an ESQL/C function.

  3. If more than one data value needs to be populated, then create an array. Pass the pointer of the array to the ESQL/C function.

  4. If more than one variable needs to be populated, then create a structure or a linked list and pass the structure or linked list pointer to the ESQL/C function.

  5. Two calls must be made to retrieve data for arrays, structures, or linked lists. In the first call, there must be an ESQL/C function call that returns the number of values to be collected. The calling function will then allocate memory in the array or structure to contain the desired data.

  6. In the second call, the data must be populated into the array, structure, or linked list.

SQL Statements
  1. Test SQL statements individually before embedding them in C code. This approach will increase the likelihood that the embedded code will work when properly incorporating the tested SQL statements. This should be a fast risk-reducing activity and a great enhancement.

  2. Capitalize all reserved words (i.e. SELECT, UPDATE, INSERT, etc.).

  3. Use ORDER BY only when absolutely needed – if the calling program does not require sorted data, do not use ORDER BY.

  4. For negative nested subqueries (selecting rows from a table where some condition in another table is not true), experiment with both the NOT EXISTS and NOT IN constructs to determine which is faster in your situation.

  5. Avoid usage of "OR" .

  6. For discrete lists of values, use the "IN" operator,( e.g. "WHERE city in (‘New York’, ‘Sydney’)) " instead of "WHERE city = ‘New York’ OR city = ‘Sydney’" .

  7. The SELECT statement follows these rules:

    • Keywords are left justified.

    • Alias table names will be used to prefix every selected column.

    • In the WHERE clause, list join expressions before restrictions.

  8. Where the select statement does not fit on a single line, align the columns from the various lines as in the following excerpt of code.

    SELECT e.emp_id, e.emp_nm, e.city_nm, d.dept_nm
    FROM emp e, dept d
    WHERE e.dept_id = d.dept_id;

  9. The UPDATE statement follows these rules:

    • Keywords are left justified.

    • First line is "UPDATE tablename" .

    • Next lines specify updated columns and their values.

    • Final lines are the WHERE clause.

  10. The following excerpt of source code exhibits the above rules.

    UPDATE emp
    SET job_desc = \//,
    City_nm = 'Sterling'
    WHERE emp_nm = 'JOE';

  11. The DELETE statement follows these rules:

    • Keywords are left justified.

    • First line is "DELETE FROM tablename" .

  12. The following excerpt of source code exhibits the above rules.

    DELETE FROM emp
    WHERE city_nm = 'Sterling';

  13. User parentheses rather than the implicit SQL precedence rules for logical operators in a WHERE clause. Consider the following excerpts of source code, the first excerpt is incorrect, the second excerpt is correct.

    SELECT COUNT(*)
    FROM emp
    WHERE job_desc LIKE 'widget%'
    AND name LIKE 'J%'
    OR city = 'Sterling';

    SELECT COUNT(*)
    FROM emp
    WHERE (job_desc LIKE 'widget%' AND name LIKE 'J%')
    OR city = 'Sterling';

  14. For further information refer to the Enterprise Standards Profile (ESP) Attachment 1 Enterprise Data Standards and Guidelines.

Whitespace

  1. Use vertical and horizontal whitespace judiciously to make the program more readable.

  2. Ensure that indentation and spacing reflect the block structure of the code.

Vertical Spacing of Conditional Operators on Separate Lines
  1. Split a long string of conditional operators onto separate lines. For example consider the following excerpt.

    if (foo-<next == NULL
    && total_count > needed
    && needed >= MAXLLOT
    && ServerActive(current -input))
    {
    ...
    }

  2. Similarly, split elaborate "for" loops onto different lines.

    for (curr = *listp, trail = pList;
    curr != NULL;
    trail = &(curr-<next), curr = curr-<next) {
    DoSomething();
    DoAnotherSomething();
    }

Spacing for Parentheses
  1. Do not separate keywords that are followed by expressions in parentheses from the left parenthesis.

  2. Put blanks after commas in argument lists to help separate the arguments visually.

Portability

  1. Here, "portable" means that a source file can be compiled and executed on different machines with the only change being the inclusion of possibly different header files and the use of different compiler flags. The header files will contain #defines and typedefs that may vary from machine to machine.

  2. In general, a new "machine" is different hardware, a different operating system, a different compiler, or any combination of these.

    • Be aware that the size of different data types may vary from platform to platform.

    • Be especially careful to avoid making assumptions about integers and pointers.

    • Be aware that the precision and storage format of floating point numbers may vary from platform to platform.

    • Do not assume that software will always be executed on the machine for which it is originally designed.

Machine-Dependent Code Placement
  1. Place all machine-dependent code in a separate file from all machine-independent code.

  2. Machine-dependent code must be #ifdef'ed so that an informative error message will result if the code is compiled on a machine other than for which it is designed.

Machine-Dependent Code Usage
  1. Only write machine-dependent code when necessary.

  2. Even if, for example, a particular piece of hardware requires that a machine-dependent routine be written, try to write any routines that support the machine-dependent code machine-independent.

C++ Programming

  1. This subsection provides establishes controls to ensure coding of C++ programs are reliable, maintainable and portable whether developed by IRS or outside vendors.

SCOPE

  1. These standards apply to all C++ programming for any project however, these standards and guidelines do not apply to source code that is generated by a tool (such as a Graphical User Interface (GUI) builder), or purchased as pre-existing software from a third party.

Classes

  1. Classes are a very significant part of your C++ programs. Classes are where most of the processing in your programs occurs. Classes are also one of the C++ constructs where you have choices such as different types of constructors and destructors or different types of operators and assignments. The following standards will help you in writing good C++ class code.

Class Declaration
  1. All classes shall declare an assignment operator.

  2. Headers files shall not contain more than one class definition.

  3. Header files shall not declare variables other than class member data.

  4. Class names shall be unique irrespective of case in any namespace including the IRS global namespace.

  5. Class member data shall have a trailing"_" appended to their variable name, to distinguish them from local variables within member functions. No other variables shall be named with a trailing underscore.

  6. Class declarations shall be made using the following order:

    1. Friend declarations

    2. Public members

    3. Protected members

    4. Private members

    Example: class C // correct access order { public: // ... protected: // ... private: // ... };

  7. Within the public, protected and private sections of the class declaration the following order shall be followed:

    1. Type declarations

    2. Data members

    3. Constructors

    4. Destructors

    5. Mutators

    6. Accessors

  8. The name of the class definition header file must match the name of the class implementation file.

Constructors and Destructors
  1. All classes shall declare a copy constructor if dynamic memory allocation is involved.

  2. Classes that are meant to be instantiated only by their subclasses shall have their constructor(s) and destructor declared protected.

  3. Constructors other than the copy constructor that have only one parameter shall be declared explicitly.

  4. Classes with virtual functions and Classes with children shall define a virtual destructor.

Class Data Initialization
  1. Data members shall be initialized in the order in which they are declared.

  2. Never declare non-const public data variables. Classes shall declare member data private or protected. Always access non-const data through public access methods.

Class Execution
  1. A member function shall never return a reference or a pointer to a local variable. This will result in a pointer referencing a variable that has gone out of scope when the function returns.

  2. A member function that does not modify member data shall be declared const.

  3. A public member function shall never return a non-const reference or pointer to member data.

  4. A public member function shall never return a non-const reference or pointer to data outside an object, unless the object shares the data with other objects.

  5. No member functions shall be implemented within the class header declaration. The only exceptions are accessors and mutators (gets and sets).

  6. If the behavior of an object is dependent on data outside the object, this data shall not to be modified by const member functions.

  7. Avoid overloading on a pointer type.

  8. An assignment operator shall return a reference to the assigning object (as the assignment operator returns the left hand side (LHS)). Non-const reference is consistent with the behavior of built-in types.

  9. When overloading the assignment operator, assignment to self shall be checked by adding the check at the beginning of the assignment method.

Inheritance
  1. Inheritance shall not be used for parts-of relations. Use template classes for parts-of relations.

  2. Use inheritance to implement a generalization to specialization (kind of) relationships.

  3. Inherited non-virtual member functions shall not be overridden.

Initialization
  1. Uninitialized data present in variables, objects, etc. have led to many problems. Often the problems manifest themselves as the very difficult "unable to reproduce" kind of problem at test time since the behavior of programs is dependent on the content of unitialized variables, which may or may not change with every execution.

Initialization of Variables
  1. Initialize all static variables explicitly.

  2. Always initialize object instance variables of all types.

  3. Every variable that is declared shall be initialized before it is used.

Initialization of Classes
  1. Use constructor initializer lists to ensure that every instance variable in a class has a defined value.

  2. When allocating objects, ensure that all pointers to the objects are initialized via an initializer list or within the body of the constructor.

  3. Classes that allocate dynamic storage shall define a destructor that releases that storage.

  4. After deleting the object in a destructor, set the pointer to NULL.

Variables Scope

  1. Header files shall use forward declarations instead of including header file(s).

  2. Global variables including using the C style extern declaration shall not be used unless the need is clearly documented and described for maintainers. Use namespaces to declare broad scope variables.

  3. File scope and static variables shall be defined using the unnamed namespace.

  4. Names occurring in close proximity to the current scope, including an enclosed scope, shall not be redefined.

  5. Do not write code that is dependent on the lifetime of a temporary variable.

Data Types

  1. A const shall never be converted to a non-const, except when handling an exception.

  2. Use struct when a user-defined type contains only data. Use classes when a user-defined type contains data and code that processes the data.

  3. Predefined types shall not be redefined.

  4. Do not define boolean types. The predefined boolean values " true" and "false" shall be used.

  5. Do not declare the structure type and its associated variable in the same statement. Instead, declare the structure type first, and then declare a variable of that type.

  6. Use the const type qualifier to identify data that should not change during execution. The compiler will flag attempts to change const variables, which aids debugging.

  7. The size of an array shall be declared with an enum constant or const. This makes modifying the size of an array easier, and is more meaningful to the reader.

  8. Do not use the volatile qualifier. The purpose of volatile is to suppress optimization that can "optimize out" low level access to hardware.

  9. The use of numeric values (magic numbers) in code shall be avoided. Use descriptive constants instead, with the exception that the numbers 0 and 1 are permitted if their use is self-explanatory.

Conditional Constructs

  1. Logical expressions of the type if(test) or if(!test) shall not be used when test is a pointer, or the test is the return of a function which returns a non-boolean value.

  2. The "? :" operators shall not be used.

  3. A break statement shall terminate the code following each case label.

  4. The flow control primitives if, else, while, for and do shall be followed by a block, even if it is an empty block.

  5. The switch statement shall always utilize the default statement.

  6. For boolean expressions ('if', 'for', 'while', and 'do') involving non-boolean values, always use an explicit test of equality or non-equality.

  7. Avoid conditional expressions that always have the same result.

File Prologs

  1. A file prolog shall be used at the beginning of all source code files (header, implementation and main program files), appearing as the first item of the file. The following section provide the required prologs for C++ header and implementation files (including main programs). The following file naming convention shall be used:

    File Type File Name/Suffix
    C++ Header file .h
    C++ Implementation file (non-main) .cpp
    C++ Implementation file (main) main.cpp

File Size and Structure
  1. The section cites standards for File Size and Structure.

File Size
  1. Unless precluded by the system or project requirements, C++ classes shall define class member functions for a single class in a single file (i.e., one .cpp file per class, defining all methods for that class).

File Structure
  1. Developers shall declare classes, data structures, layouts, functions, variables, and constants in a header file named classname.h.

  2. The implementation of class methods, functions, and definition of non-static storage variables for each header file shall be located in a corresponding classname.cpp file.

Name Conventions
  1. While such names may be permitted by C++ standard and supported by compilers, names that very solely by case tend to create readability problems for the maintenance programmer.

General Naming Conventions
  1. Do not use names that vary solely by case.

  2. Do not use typedef to emphasize distinct numeric categories. Use a class definition instead.

  3. C++ names for all constructs such as classes, functions, variables, etc. shall use the intercap convention. Intercap runs all words of a descriptive name together without underscores. An exception is made for names for constants

  4. The following shall use the Capital form:

    1. Classes and Structures (nominal Classes)

    2. enum tagnames

Identifiers
  1. Identifiers shall adhere to the conventions for ANSI standard C++.

  2. Variable and function identifiers shall use the normal form of the intercap notation. That is, the names of variables and functions shall begin with a lowercase letter.

  3. Do not use single variable names unless it is an index in a loop.

Functions and Parameter
  1. The names of formal arguments to functions shall be specified and shall be the same both in the function declaration and in the function definition.

Constants
  1. Define constants using fully capitalized words separated by underscore.

  2. Define constants using const or enum. Do not use #define.

Formatting

  1. The IRS C++ standard indentation level is defined as 4 spaces; the programmer shall follow proper indentations to ensure readability and consistency of the C++ source code.

  2. Block statements shall be indented one indentation level to show scope and structural coherence.

Indentation
  1. Indent the continued part of a statement at least one indentation level beyond the start of the statement.

  2. Indentation shall be performed using spaces instead of tab characters.

  3. Indentation shall be consistent throughout all source files.

Spacing
  1. The '*' and '&' shall be directly connected with the type names in declarations and definitions. I.e., no space shall be placed between the '*' or '&' and the type names in declarations and definitions.

  2. There shall be no spaces between a function name and the left parentheses.

Grouping
  1. Begin each statement on a separate line.

  2. Limit the length of source statements so that complete source statements is visible on the screen without having to scroll right and left repeatedly.

  3. Braces ("{}" ) that enclose a block shall be placed in the same column, on separate lines directly before and after the block.

Includes
  1. Each header file shall #include any other headers on which it directly depends.

  2. #includes shall precede any declarations or definitions in a file.

  3. #include shall not be used to insert executable code into a file or to insert part of a class definition from an external file unless it is required by the use of software developed externally to the project, such as commercial off-the-shelf (COTS) products.

  4. Place #include statements in the following order:

    1. (If a .cpp file) the corresponding header file

    2. System header files

    3. COTS header files

    4. Project specific header files.

Functions

  1. The section cites standards for Functions and Declarations.

Declarations
  1. Function prototypes and external variables shall be declared in a header file (to avoid multiple declarations), not in implementation files.

Function Parameters
  1. The return type of a function shall always be stated explicitly. Functions that do not return a value shall be declared as void.

  2. Pass parameters in input, modify, output order.

  3. Variable argument lists shall not be used (ellipses notation).

  4. Where the return value from functions are stored for future use, the function invocation shall not be embedded in conditional or other function invocations. Functions may be embedded if return value is only used within that source.

  5. Check the fault codes that may be received from library functions even if these functions seem fool proof.

Function Invocation, Execution, and Return
  1. Do not depend on the order of evaluation of arguments to a function.

  2. Always return a value from main().

  3. For functions with non-void return type, ensure that all paths have a return statement that contains an expression of the return type.

Error Handling

  1. Error notification, memory cleanup is very important in error-handling situations. The programs need to have a consistent way of handling memory deallocations.

General Error Handling
  1. Calling functions shall check for errors reported from functions

Throwing Exceptions
  1. Do not throw exceptions from within destructors.

  2. Throw only objects of class type.

Handling Exceptions
  1. Avoid memory leaks in exception handling code by using references in parameter lists for exception handlers.

Expressions

  1. Avoid using shift operations instead of arithmetic operations and validate arguments to be used in shift operators.

Expression Arithmetic
  1. Pointer arithmetic shall not be used.

  2. Do not depend on the behavior of underflow or overflow.

  3. Apply unary minus to operands of signed type only.

Type Conversions
  1. Code shall not depend on implicit type conversions.

  2. The following assignments shall not be used:

    1. Assigning a pointer value to a non-pointer object

    2. Assigning a non-pointer value to a pointer object

    3. Assigning a function-pointer value to a data-pointer object

    4. Assigning a data-pointer value to a function-pointer object

  3. Do not convert floating values to integral types except through use of standard library routines.

Pointers in Expressions
  1. A pointer shall not be compared to NULL or assigned NULL without casting the NULL to the proper type.

Comments

  1. Use // for in-line comments. Use /* and */ for block comments.

Memory Management

  1. If a function is returning an allocated object that the caller must free, then the memory for the allocated object shall be documented in the filename.h file as well as in any function comment header block that is used.

  2. When memory allocated to a pointer has been deleted, a new value shall be assigned to the pointer or the pointer should be deleted.

Heap and Stack Memories
  1. Do not allocate dynamic objects contained within other objects as instance data.

  2. Class authors shall provide default values for dynamic objects within other objects and/or constructors that can be used on initializer lists.

Memory Leaks
  1. Save the address of allocated memory to prevent orphaned allocation.

  2. Explicitly deallocate a dynamically allocated segment prior to assigning a new value.

  3. Avoid memory leaks in exception handling code.

  4. Do not use code that can throw an exception in a destructor.

  5. Avoid memory leaks involving external components.

  6. Avoid memory leaks involving reuse of "dead" objects.

  7. Avoid memory leaks by explicitly clearing memory after use.

  8. Avoid memory leaks by unfreezing frozen stream objects.

  9. Avoid memory leaks by ensuring that you write the operator delete whenever the operator new has been written for a class.

Buffers Overflows
  1. The size of an array shall be declared with an enum constant or const. This makes modifying the size of an array easier, and is more meaningful to the reader.

  2. When reading array contents, check to ensure that the index does not exceed the array size.

  3. When adding to an array, check to ensure that the size of the array can hold the existing content in addition to the new contents to be added.

  4. Always test a pointer’s value for NULL before using it.

Java Programming

  1. This section of the IRM provides controls to ensure Java programs are reliable, maintainable, and portable.

File Names

  1. Use the following controls for File names.

File Suffixes
  1. Java Software uses the following file suffixes:

    File Type Suffix
    Java source .java
    Java bytecode .class
Common File Names
  1. Frequently used file names include:

    README The preferred name for the file that summarizes the contents of a particular directory.
    build.xml Default build for Ant.

File Organization

  1. Use the following controls for File Organization.

General
  1. A file consists of sections, separated by blank lines and an optional comment identifying each section

  2. Avoid files longer than 2000 lines, since they are cumbersome.

Java Source Files
  1. Each Java source file contains a single public class or interface.

  2. When private classes and interfaces are associated with a public class, put them in the same source file as the public class.

  3. Make the public class the first class or interface in the file.

  4. Order Java source files as follows:

    • Beginning comments

    • Package and Import statements

    • Class and interface declarations

Beginning Comments
  1. Begin all source files with a C-style comment that lists the class name, version information and date:

    /*

    * ClassName

    *

    * Version information

    *

    * Date

    *

    */

  2. Use available tools to manage version and date information.

Package and Import Statements
  1. The first non-comment line of most Java source files is a package statement. After that, import statements can follow. For example:

    package java.awt;

    import java.awt.peer.CanvasPeer;

  2. The first component of a unique package name is always written in all-lowercase ASCII letters and should be one of the top-level domain names, currently com, edu, gov, mil, net, org, or one of the English two-letter codes identifying countries as specified in ISO Standard 3166 of 1981.

  3. Package statements will follow the convention gov.irs.project or gov.irs.program.project as determined by the program or project.

Indentation

  1. Use the following controls for Indentation.

Line Length
  1. Lines should be broken/ wrapped at column 100 for readability.

  2. Lines longer than 80 characters, while allowed, may affect readability since they are not handled by many terminals and tools.

  3. Examples for use in documentation should have no more than 70 characters.

Wrapping Lines
  1. When an expression will not fit on a single line, break it according to these general principles:

    • Break after a comma.

    • Break before an operator.

    • Prefer higher-level breaks to lower-level breaks

    • Align the new line with the beginning of the expression at the same level on the previous line.

    • Indent four spaces if these rules lead to confusing code or to code that's squished up against the right margin.

  2. How to break the lines of method

    someMethod(longExpression1, longExpression2, longExpression3,

    longExpression4, longExpression5);

    var = someMethod1(longExpression1,

    someMethod2(longExpression2,

    longExpression3));

  3. How to break an arithmetic expression. The first example is preferred, since the break occurs outside the parenthesized expression, which is at a higher level.

    longName1 = longName2 * (longName3 + longName4 - longName5)
    + 4 * longname6; // PREFER
    longName1 = longName2 * (longName3 + longName4
    - longName5) + 4 * longname6; // AVOID

  4. How to indent method declarations. The first example follows the conventional practice. The second indents 4 spaces because the conventional indentation would shift the second and third lines too far to the right.

    //Conventional Indentation.
    someMethod(int anArg, Object anotherArg, String yetAnotherArg,
    Object andStillAnother) {
    ...
    }

    //Indent 4 Spaces To Avoid Deep Indents

    private static synchronized workingLongMethodName(int anArg,

    Object anotherArg, String yetAnotherArg,

    Object andStillAnother) {

    ...

    }

  5. Line wrapping of If statements should generally use the 4-space rule, making it easier to see the body of the statement. For example:

    //Use this indentation

    if ((condition1 && condition2)

    || (condition3 && condition4)

    ||!(condition5 && condition6)) {

    doSomethingAboutIt();

    }

    //Or use this

    if ((condition1 && condition2) || (condition3 && condition4)

    ||!(condition5 && condition6)) {

    doSomethingAboutIt();

    }

  6. Here are three acceptable ways to format ternary expressions:

    alpha = (aLongBooleanExpression) ? beta : gamma;
    alpha = aLongBooleanExpression) ? beta
    : gamma;
    alpha = aLongBooleanExpression)
    ? beta
    : gamma;

Comments

  1. Java programs can have two kinds of comments: implementation comments and documentation comments.

Implementation Comments
  1. Implementation comments are like those found in C++, which are delimited by /*...*/, and //.

  2. Implementation comments are meant for commenting out code or for comments about the particular implementation.

Implementation Comment Formats
  1. There are four types of implementation comments: block, single-line, trailing, end-of-line.

Block Comments
  1. Use Block Comments to provide descriptions of files, methods, data structures and algorithms. Block comments inside a function or method should be indented to the same level as the code they describe.

  2. Block Comments may be placed at the beginning of each file, before each method, or immediately after the imports.

  3. Precede a block comment with a blank line to set it apart from the rest of the code.

    /*

    * Here is a block comment.

    */

  4. Block comments can start with /*-For example:

    /*-

    * Here is a block comment

    * one

    * two

    * three

    */

Single-Line Comments
  1. Place short comments on a single line indented to the level of the code that follows.

  2. Precede a single line comment with a blank line. Here is an example of a single-line comment in Java code:

    if (condition) {
    // Handle the condition.
    ...
    }

Trailing Comments
  1. Very short comments can appear on the same line as the code they describe. Shift these comments far enough right to separate them from the statements they describe.

  2. More than one short comment may appear in a chunk of code. Indent to the same tab setting. Here is an example of a trailing comment in Java code:

    if (a == 2){ {
    return TRUE; /* special case */
    } else {
    return isPrime(a); /* works only for odd a */
    }

End-Of-Line Comments
  1. Use the // comment delimiter to comment out either a complete line or a partial line.

  2. Also, it can be used in consecutive multiple lines for commenting out sections of code. Examples of all three styles follow

    if if (foo < 1) {
    // Do a double-flip
    ....
    }
    else {
    return false; // Explain why here.
    }
    //if (bar < 1) {
    //
    // // Do a triple-flip.
    // ....
    //}
    //else {
    // return false;
    // }

    :

Documentation Comments
  1. Documentation comments (known as "doc comments " ) are Java-only, and are delimited by /**...*/.

  2. Doc comments can be extracted to HTML files using the javadoc tool.

  3. Doc comments are meant to describe the specification of the code, from an implementation-free perspective, to be read by developers who might not necessarily have the source code at hand.

  4. For further details, see "How to Write Doc Comments for Javadoc" which includes information on the doc comment tags (@return, @param, @see): http://java.sun.com/javadoc/writingdoccomments. For further details about doc comments and javadoc, see the javadoc home page at: http://java.sun.com/javadoc/

  5. Doc comments describe Java classes, interfaces, constructors, methods, and fields. Set each doc comment inside the comment delimiters /**...*/, with one comment per class, interface, or member. Place this comment just before the declaration:

    /**
    * The Example class provides ...
    */
    public class Example { ...

  6. Notice that top-level classes and interfaces are not indented, while their members are. The first line of the doc comment (/**) for classes and interfaces is not indented; subsequent doc comment lines each have 1 space of indentation (to vertically align the asterisks). Members, including constructors, have 4 spaces for the first doc comment line and 5 spaces thereafter.

  7. If you need to give information about a class, interface, variable, or method that is not appropriate for documentation, use an implementation block comment (see Section 5.2.1) or single-line comment (Section 5.2.2) immediately after the declaration. For example, place details about the implementation of a class in such an implementation block comment following the class statement, not in the class doc comment.

  8. Do not position doc comments inside a method or constructor definition block because Java associates documentation comments with the first declaration after the comment.

General
  1. Ensure that comments provide a code overview and additional information that is not readily available in the code itself.

  2. Ensure that comments contain only information that is relevant to reading and understanding the program. For example, do not include information about how the corresponding package is built or in what directory it resides as a comment.

  3. Providing non-trivial or non-obvious design decisions in comments is appropriate, but avoid giving information that is clear from the code

  4. Avoid any comments that are likely to become dated as the code evolves.

  5. Frequent comments sometimes reflect poor quality code. When you feel compelled to add a comment, consider rewriting the code to make it clearer.

  6. Do not enclose comments in large boxes drawn with asterisks or other characters.

  7. Never include special characters such as those for form-feed and backspace in comments.

Declarations

  1. Use the following controls for declarations.

Number Per Line
  1. Use one declaration per line to encourage commenting. In other words,

    int level; // indentation level
    int size; // size of table

    is preferred over

    int level, size;

  2. Do not put different types on the same line. For example:

    int foo, fooarray[]; //WRONG!

    The previous examples use one space between the type and the identifier. Another acceptable alternative is to use tabs, e.g.:

    int level; // indentation level
    int size; // size of table
    Object currentEntry; // currently selected table entry

Initialization
  1. Initialize local variables where they are declared, unless the initial value depends on some computation occurring first.

Placement
  1. Declarations may be placed at the beginning of blocks. A block is any code surrounded by curly braces "{" " code }" .

    void myMethod() {
    int int1 = 0; // beginning of method block
    if (condition) {
    int int2 = 0; // beginning of "if" block
    ...
    }
    }

  2. Indexes offor loops can be declared in the for statement:

    for (int i = 0; i > maxLoops; i++) { ... }

  3. Avoid local declarations that hide declarations at higher levels. For example, do not declare the same variable name in an inner block:

    int count;
    ...
    myMethod() {
    if (condition) {
    int count = 0; // AVOID!
    ...
    }
    ...
    }

  4. Local variables should be declared immediately prior to usage.

Class and Interface Declarations
  1. When coding Java classes and interfaces, follow these formatting rules:

    • No space between a method name and the parenthesis " (" starting its parameter list

    • Open brace "{" may appear at the end of the same line as the declaration statement or on the next line by itself.

    • Closing brace "}" starts a line by itself indented to match its corresponding opening statement, except for null statements, where the "}" should appear immediately after the "{" .

      class Sample extends Object {
      int ivar1;
      int ivar2;
      Sample(int i, int j) {
      ivar1 = i;
      ivar2 = j;
      }
      int emptyMethod() { }
      ...
      }

    • Separate methods with a blank line.

Statements

  1. Use the following controls for Java Statements

Simple Statements
  1. Use no more than one statement per line. For example:

    argv++; // Correct
    argc--; // Correct
    argv++; argc--; // AVOID!

Compound Statements
  1. Compound statements are statements that contain lists of statements enclosed in braces "{ statements }" . See the following sections for examples.

    • Indent enclosed statements one more level than the compound statement.

    • The opening brace may be at the end of the line that begins the compound statement. Ensure the closing brace begins a line and indents to the beginning of the compound statement.

    • Braces are used around all statements, even single statements, when they are part of a control structure, such as an if-elseorfor statement. If braces are not used, inadvertent errors will be introduced, when adding other statements later on.

return Statements
  1. Do not use parentheses with areturnstatement that has a value unless the parentheses make the return value more obvious in some way. For example:

    return;
    return myDisk.size( );
    return (size ? size : defaultSize);

if, if-else, if else-if else Statements
  1. Use the following form for the if-else class of statements:

    if (condition) {
    statements;
    }
    if (condition) {
    statements;
    } else {
    statements;
    }
    if (condition) {
    statements;
    } else if (condition) {
    statements;
    } else {
    statements;
    }

  2. if statements always use braces { }. Avoid the following error-prone form

    if (condition) //AVOID! THIS OMITS THE BRACES { }!
    statement;

    :

for Statements
  1. Use the following form for a forstatement:

    for (initialization; condition; update) {
    statements;
    }

  2. Use the following form for an empty for statement (one in which all the work is done in the initialization, condition, and update clauses):

    for (initialization; condition; update);

  3. When using the comma operator in the initialization or update clause of a for statement, avoid using more than three variables. If needed, use separate statements before the for loop (for the initialization clause) or at the end of the loop (for the update clause).

while Statements
  1. Use the following form for a while statement:

    while (condition) {
    statements;
    }

  2. Use the following form for an empty whilestatement:

    while (condition);

do-while Statements
  1. Use the following form for ado-whilestatement:

    do {
    statements;
    } while (condition);

switch Statements
  1. Use the following form for a switch statement:

    switch (condition) {
    case ABC:
    statements;
    /* falls through */
    case DEF:
    statements;
    break;
    case XYZ:
    statements;
    break;
    default:
    statements;
    break;
    }

  2. Every time a case falls through (does not include a break statement), add a comment where the break statement would normally be. This is shown in the preceding code example with the / * falls through */ comment.

  3. Include a default case in every switch statement. The break in the default case is redundant, but it prevents a fall-through error if another case is added later on.

Exceptions

  1. Exceptions handle errors and other exceptional events that disrupt the normal flow of instructions. The runtime system searches the call stack for a method that contains a block of code, called the exception handler, which handles the exception

General
  1. Even though you write the main flow of your code and deal with the exceptional cases elsewhere, it is important to code your exceptions at the same time you are composing your normal programming logic

  2. Handle all potential exceptions applicable to your code.

  3. Group exceptions within related classes with the most general on top and more specific ones lower in the hierarchy; generally you want exception handlers to be as specific as possible.

  4. When you use general exception handling, explain your rationale in a documentation comment so that programmers who later maintain your code understand your intentions.

  5. Aim for consistency; if you write exception handling for an aggregate of object types, do not do exception handling for one of the contained objects.

  6. Use exceptions appropriate to your class type, e.g., associate FileNotFoundExceptions with file handling classes, IOException with I/O classes, and ArrayOutOfBoundsException with array classes.

Exception Types
  1. Use checked exceptions to report errors that may occur, however rarely, under normal program operation. Checked exceptions are subject to the Catch or Specify Requirement.

  2. Use unchecked exceptions, errors and runtime exceptions, to report serious, unexpected errors that may indicate an error in the program’s logic, e.g., using an out-of-bound index, dividing by zero or referencing a null pointer. Since termination is imminent, ensure that your program shuts down gracefully.

  3. Use a finally block to release open resources and return the system to a prior safe state. Use a more general, rather than a more exact exception, in these cases. The compiler does not require that you catch or specify runtime exceptions, such as the NullPointerException.

Logging Exceptions
  1. Even when you code a catch block to catch an exception you do not expect to occur, log information that can support corrective action.

  2. Follow the default logging mechanism for your project.

Try-Catch-Finally
  1. Java code must adhere to the Catch or Specify Requirement in order to compile. Code that might throw certain exceptions must be enclosed either by:

    • Atrystatement followed by acatch statement or

    • A method that provides a throws clause to list the exception.

  2. A try block that encloses the exception throwing statements generally looks like the following:

    try {
    code
    }
    catch (ExceptionType name) {
    }
    catch (ExceptionType2 name) {
    }

  3. Exception handlers immediately follow the try block and are denoted by the keyword catch. List low-level catch clauses first, list others in a progressively higher fashion, ending with top-level exceptions.

  4. Top-level exceptions are those that are applicable to virtually all programming activities. It is better to use top-level exceptions in the catch clause, then in thefinallyclause. Use a finallyclause, even when it appears unnecessary.

  5. The finally clause always executes and signifies actions to be taken regardless of whether an exception has been caught or not or thrown or not. A finally clause is used for tasks such as closing files or network connections or recovering resources. A finally block occurs below all catch statements, at the end of the try-catchblock and has the syntax:

    finally {
    }

Throwing Exceptions
  1. If you do not handle an exception as described previously, throw the exception, by adding a throws clause to the method declaration. The throws clause comprises the throws keyword followed by a comma-separated list of all the exceptions thrown by that method. The clause goes after the method name and argument list and before the brace that defines the scope of the method.

  2. In order to improve the maintainability of your code, include both the checked and unchecked exceptions thrown by the method.

  3. Throwing exceptions of type Throwable, Error or Exception are often too general to be meaningful to the exception handler.

Chained Exceptions
  1. An application often responds to an exception by throwing another exception. Chain such exceptions together to provide useful information to the programmer or use a stack trace to provide the programmer with information about the execution history.

User Defined Exceptions
  1. Write your own exception classes only if

    • the exception type is not provided by the Java API (or by a vendor API)

    • programmers using your code must discriminate between the exceptions you throw and those provided by the Java API (or vendor API)

    • you need to package your code without depending on the exception types located in other packages or

    • your code throws several exception types with one semantic meaning.

  2. For the exception classes you write, append Exception to the name of the class and follow the conventions for checked and unchecked exceptions indicated above.

  3. Declare all fields of exception classes as finalor private, since the data carried in objects of exception classes should be protected from unauthorized or accidental modifications.

Naming Conventions

  1. Naming conventions make programs more understandable and easier to read. They can also give information about the function of the identifier. Knowing, for example, whether the identifier is a constant, package, or class makes the code easier to understand.

    Identifier Type Rules for Naming Examples
    Packages The prefix of a unique package name is always written in all lowercase ASCII letters and should be one of the top-level domain names, currently com, edu, gov, mil, net, org, or one of the English two-letter codes identifying countries as specified in ISO Standard 3166, 1981. Subsequent components of the package name vary according to an organization's own internal naming conventions. Such conventions might specify that certain directory name components be division, department, project, machine, or login names. com.sun.eng com.apple.quicktime.v2 edu.cmu.cs.bovik.cheese
    Classes Class names should be nouns, in mixed case with the first letter of each internal word capitalized. Try to keep your class names simple and descriptive. Use whole words and avoid acronyms and abbreviations (unless the abbreviation is more widely used than the long form, such as a URL or HTML). class Raster ;
    class ImageSprite;
    Interfaces Interface names should be capitalized like class names. interface RasterDelegate; interface Storing;
    Methods Methods should be verbs, in mixed case with the first letter lowercase and the first letter of each internal word capitalized. run ( );
    runFast( );
    getBackground ( );
    Variables Except for variables, all instance, class, and class constants are in mixed case with a lowercase first letter. Internal words start with capital letters. Variable names should not start with an underscore _ or dollar sign $ characters, even though both are allowed. Variable names should be short yet meaningful. The choice of a variable name should be mnemonic and designed to indicate to the casual observer the intent of its use. One-character variable names should be avoided except for temporary " throwaway " variables. Common names for temporary variables are i, j, k, m, and n for integers and c, d, and e for characters. int i;
    char c;
    float myWidth;
    Constants The names of variables declared class constants and of ANSI constants should be all uppercase with words separated by underscores ("_" ). ANSI constants should be avoided, for ease of debugging. static final int
    MIN_WIDTH = 4;
    static final int
    MAX_WIDTH = 999;
    GET_THE_CPU = 1;

Programming Practices

  1. Use the following controls for programming practices.

Providing Access to Instance and Class Variables
  1. Do not make instance or class variables public without good reason. Often, instance variables do not need to be explicitly set. Often they are set as a side effect of method calls. A class which is essentially a data structure, with no behavior, is an example of an appropriate public instance variable.

  2. If you would have used the keyword struct instead of the keyword class (while coding in C or C++, not in Java; Java does not support the struct keyword), then it would be appropriate to make the class's instance variables public.

Referring to Class Variables and Methods
  1. Do not use an instance object to access a class (static) variable or method. Use the class name instead. For example:

    classMethod(); //OK
    AClass.classMethod(); //OK
    anObject.classMethod //AVOID!

Constants
  1. Avoid coding numerical constants (literals) directly, except for -1, 0, and 1, which can appear in a for loop as counter values.

Variable Assignments
  1. Avoid assigning several variables to the same value in a single statement because it is hard to read. For example:

    fooBar.fChar = barFoo.lchar = 'c'; // AVOID!

  2. Do not use the assignment operator withinif, while, or do-whilestatements, where it can be easily confused with the equality operator.

  3. Do not use embedded assignments in an attempt to improve run-time performance. This is the job of the compiler. For example:

    d = (a = b + c) + r; // AVOID!

    should be written as

    a = b + c;

    d = a + r;

Miscellaneous Practices
  1. Use the following controls for Miscellaneous Practices

Parentheses
  1. Use parentheses liberally in expressions involving mixed operators to avoid operator precedence problems. Even if the operator precedence seems clear to you, it might not be to other programmers, who do not know precedence as well as you do.

    if (a == b && c == d) // AVOID!

    if ((a == b) && (c == d)) // RIGHT

Returning Values
  1. Make the structure of your program match the intent. For example:

    if (booleanExpression) {

    return true;

    } else {

    return false;

    }

    should be written instead as

    return booleanExpression;

    Similarly,

    if (condition) {

    return x;

    }

    return y;

    should be written as

    return (condition ? x : y);

Expressions before ‘?' in the Conditional Operator
  1. If an expression containing a binary operator appears before the ? in the ternary ?: operator, parenthesize it. For example:

    (x <= 0) ? x : -x;

Special Comments
  1. Use XXX in a comment to flag something that is not a Best Practice, but works. Use FIXME to flag something that is not a Best Practice and does not work.

Security Features

  1. Use the following controls to ensure the security of Java code.

Access Guidelines
  1. Java, like C++, has ways to control access to variables and methods of objects.

Access modifiers
  1. Methods and variables labeled as public are visible, accessible and inheritable from any class in its package

  2. The protectedmodifier allows access to classes in the same package and to subclasses, inside and outside the package.

  3. The default modifier allows access by other classes in the same package.

  4. Methods and variables declared as private are accessible only within their class. Less access is given when changing from public access to protected, default or privateaccess, from protectedto default or private access, or from default to privateaccess.

  5. Use the minimum accessibility necessary to implement the responsibilities of a package, class, method, or variable.

  6. Set class variables and methods which implement the internal workings of the class behavior as privateand to use accessor methods (e.g., getVariable() and setVariable()) to read and change these variables and methods

  7. Theprivate keyword means that only that particular class, inside methods of that class, can access that member. Private variables and methods are also not inherited by subclasses.

  8. Document and justify using the other access modifiers: public and protected.

  9. Use the package access modifiers: public, protectedor private, to explicitly grant (or restrict) access to the classes in your package and thus to control how other code accesses your code. In order to make clear distinctions, mark a package explicitly as public, protected or private rather than as default.

Inner classes
  1. When possible, use adaptors, decorators, or other class designs instead of inner classes, classes nested within the scope of another class.

  2. To thwart security breeches with nested classes, set the security properties in the $JAVA_HOME/lib/security/java.security file, to explicitly define the contents of your packages. Alternatively, you can also bundle your packaged classes into a sealed JAR (Java ARchive) file.

  3. Since Java uses packages to provide namespace encapsulation, downloaded classes have a different namespace than local classes and classes loaded from different hosts will not communicate with one another within the JVM-space. Configuring the security file or using JAR files helps prevent damaging code from being included in your package namespace.

Keys, Signing and Privileged Code
  1. Use the following controls for Keys, Signing and Privileged Code.

Keys
  1. Do not store cryptographic keys or other sensitive information in your code, since this information is exposed to the JVM (Java virtual machine) and thus to accidental disclosure or damaging attacks.

  2. Using code obfuscators when storing keys in your code does not provide security, since a determined attacker can undo the code obfuscation technique and then read sensitive information.

Signed Code
  1. A digital signature is a mechanism for verifying that code comes from a trusted source. By default, keep your code unsigned. Code that is unsigned will run without any special access privileges.

  2. If using signed code, provide code-signing mechanisms that allow classes to be interrogated for signing properties. Also declare the method or class as final, as illustrated here:

    final Boolean verify(byte[]signature).

    Since the final keyword signifies that the method or class cannot be extended, subclassed or overridden, the compiler knows that there is only one version of this class or method.

  3. Place your signed and unsigned code into separate JAR (Java ARchive) files.

  4. Document and justify the use of signed code and audit and test the code appropriately.

Privileged Code
  1. Avoid writing privileged code. Privileged code runs with a full set of permissions and can be invoked by untrusted code with no permissions whatsoever.

  2. If you use privileged code, minimize the number of lines and the scope that are privileged and minimize accessibility of the privileged code through the judicious use of the access modifiers.

Safe Comparisons
  1. Compare classes using the equality operator (" = =" ) and not by name or the equals() method. Comparisons by name are unreliable, since most JVMs (Java virtual machines) will permit multiple classes with the same name. Comparison by name can allow adversary code to modify the system.DELTE THIS SUBSECTION!!!

  2. The equals() method yields results, which are less reliable than those of the equality operator.

Immutable Objects and Cloning
  1. Use the following controls for Immutable Objects and Cloning.

Immutable Objects
  1. To minimize security risks, create immutable objects whenever possible. Immutability prevents data in the objects from being accidentally or maliciously altered and improves performance as well, since locking is not required for these objects.

Cloning
  1. By default, make your classes non-cloneable to prevent malicious or errant code from assessing the system through the cloned classes.

  2. Data objects returned from your code (i.e., the return values of public methods) which cannot be made immutable, can be cloned.

  3. Be sure that your methods return the cloned copy, keeping the original for use within your code.

  4. Such standard Java data structures as Vectors and Hashtables, for instance, are not immutable and thus are returned as clones.

  5. Allow your classes to implement the java.lang.Cloneable interface only when you document and justify the need to do so.

  6. By default, make cloneable classes have a clone() method that is final. The finalmodifier means that the class cannot be changed or overridden. This prevents bogus code from re-defining the clone()method.

  7. When returning an aggregate data structure like an array, also be sure to clone the array contents and not just the array reference.

Code Example

  1. Use the following control to format Java source files.

Java Source Code File Example
  1. The following example shows how to format a Java source file containing a single public class. Interfaces are formatted similarly.

    /*
    * @(#)Blah.java 1.82 99/03/18
    *
    *
    */
    package java.blah;
    import java.blah.blahdy.BlahBlah;
    /**
    * Class description goes here.
    *
    * @version 1.82 18 Mar 1999
    * @author Firstname Lastname
    */
    public class Blah extends SomeClass {
    /* A class implementation comment can go here. */
    /** classVar1 documentation comment */
    public static int classVar1;
    /**
    * classVar2 documentation comment that happens to be
    * more than one line long
    */
    private static Object classVar2;
    /** instanceVar1 documentation comment */
    public Object instanceVar1;
    /** instanceVar2 documentation comment */
    protected int instanceVar2;
    /** instanceVar3 documentation comment */
    private Object [ ] instanceVar3;
    /**
    * ...constructor Blah documentation comment
    */
    public Blah ( ) {
    // ...implementation goes here...
    }
    /**
    * ...method doSomething documentation comment...
    */
    public void doSomething ( ) {
    // ...implementation goes here...
    }
    /**
    * ...method doSomethingElse documentation comment...
    * @param someParam description
    */
    public void doSomethingElse(Object someParam) {
    // ...implementation goes here...
    }
    }

Glossary

Case Structure: A logical control structure used when there are numerous paths to be followed depending on the contents of a given field or variable.

Conditional Statement: An instruction that use the word "IF" to test for the existence of a condition.

Program: A set of instructions that operate on input data and converts it to output.

Structure Chart

This is an Image: 33498001.gif

Please click here for the text description of the image.

COBOL Examples

This is an Image: 33498002.gif

Please click here for the text description of the image.

C Examples

This is an Image: 33498003.gif

Please click here for the text description of the image.

C Language Source Code Template

/************************************************************************
//
// Internal Revenue Service
// For Official Use Only
//
// Filename: Filename
// Description: Describe the purpose of the objects in the file,
// followed, in the case of source files, by a list
// of functions whose definitions appear in the file
// Related Files: An identification of any routines or files that
// this file may require
// Restrictions/ Known special cases where the file may not work
// Problems:
//
// Date Modified: YYYY/MM/DD
// Version id: Revision:
// Author: >First Name< >Last Name<
// Locked by: $Locker$
//
// Revision History: Will be provided by ClearCase
************************************************************************/
/*h**********************************************************
* H E A D E R F I L E S *
************************************************************/
/* System header files */
#include >stdio.h<
#include >stdlib.h<
#include >string.h<
#include >limits.h<
#include >unistd.h<
#include >signal.h<
#include >errno.h<
/* User include files */
#include "archive.h"
#include "acdbApi.h"
#include "scdbApi.h"
/*d**********************************************************
* D E F I N E S *
************************************************************/
/* Debug flags */
#ifdef FOR_MAC
#define SIGALRM 14
#end-if
/* Constants */
#define SUCCESS 0
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#end-if
/* Macros */
#define MIN(a,b) ((a)>(b)) ? (a) : (b)
/*t**********************************************************
* T Y P E D E F *
************************************************************/
typedef struct ECT_REG_HEADER_S
{
char *pFirstEntry; /* ptr to 1st registry entry */
int NumEntries; /* number of entries */
} ECT_REG_HEADER_T;
/*e**********************************************************
* E N U M S *
************************************************************/
enum TAX_FORMS_E
{
F_1040 = 0,
F_1065,
F_941_ELF,
F_941_OLF };
/*g**********************************************************
* DEFINITIONS*
************************************************************/
/* External data */
extern char *pStr; /* comments */
extern int GlobalExt; /* comments */
/* Non-static data */
int DataGl; /* comments */
char *pStr; /* comments */
/* Static data */
static int DataGl; /* comments */
static char *pStr; /* comments */
/*fp*********************************************************
* F U N C T I O N P R O T O T Y P E S (alphabetized) *
************************************************************/
int FunctionName1(int par1, char *par2_p);
Void FunctionName2(int par1, char *par2_p);
/*f******************************************************************
* Function Name: FunctionName1
* Description: A description of the major task(s) performed by
* routine. It should be a series of one or more
* simple verb/object statements
* Input parameters : par1 - description
* par2_P - description
* Output parameters: *par2_p - description
* Function return - SUCCES or FAIL
********************************************************************/
int FunctionName1(int par1, char *par2_p)
{
/* LOCAL VARIABLES and CONSTANTS*/
/* FUNCTION BODY */
return return_code;
}
/*f******************************************************************
* Function Name: FunctionName2
* Description: A description of the major task(s) performed by
* routine. It should be a series of one or more
* simple verb/object statements
* Input parameters : par1 - description
* par2_P - description
* Output parameters: *par2_p - description
********************************************************************/
void FunctionName2(int par1, char *par2_p)
{
/* LOCAL VARIABLES and CONSTANTS*/
/* FUNCTION BODY */
}

C Language Header File Template

/************************************************************************
//2
// Internal Revenue Service
// For Official Use Only
//
// Filename: Filename
// Description: Describe the purpose of the objects in the file,
//
followed, in the case of source files, by a list
// of functions whose definitions appear in the file
// Related Files: An identification of any routines or files that
// this file may require
// Restrictions/ Known special cases where the file may not work
// Problems:
//
// Date Modified: Date: YYYY/MM/DD
// Version id: Revision:
// Author: Author: >First Name< >Last Name<
// Locked by: $Locker:$
//
// Revision History: Will be provided by ClearCase
************************************************************************/
#ifndef TEMPLATE
#define TEMPLATE
/************************************************************
* D E F I N E S *
************************************************************/
/* Debug flags */
#ifdef FOR_MAC
#define SIGALRM 14
#END-IF
/* Constants /
#define SUCCESS
0
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#END-IF
/* Macros */
#define MIN(a,b) ((a)>(b)) ? (a) : (b)
/************************************************************
* T Y P E D E F S *
************************************************************/
typedef struct ECT_REG_HEADER_S
{
char *pFirstEntry; /* ptr to 1st registry entry */
int NumEntries; /* number of entries */
} ECT_REG_HEADER_T;
/************************************************************
* E N U M S *
************************************************************/
enum TAX_FORMS_E
{
F_1040 = 0,
F_1065,
F_941_ELF,
F_941_OLF
};
/********************************************************************
* F U N C T I O N P R O T O T Y P E S (alphabetized) *
********************************************************************/
int FunctionName1(int par1, char *par2_p);
void FunctionName2(int par1, char *par2_p);
#END-IF /* TEMPLATE */