Macro expansion is the preprocessor step that turns a single % invocation into many lines of Easytrieve source. Understanding expansion separates developers who debug compile errors in minutes from those who stare at a one-line %PERSNL wondering why DEPT offset is wrong. The preprocessor loads the macro definition, binds positional and keyword actuals to prototype parameters, walks each model statement replacing & tokens, and inserts the result inline. The compiler never sees the percent line—it sees generated FILE, DEFINE, and REPORT statements exactly as if typed by hand. Listings document this transformation unless LIST NOMACROS suppresses it. Nested invocations expand inner macros before outer bodies complete. This page covers the expansion pipeline, reading listings, controlling list volume, diagnosing substitution failures, verifying layouts after library updates, and relating expansion to the broader compile process you studied earlier.
12345678910111213141516171819* Source you maintain %PERSNL JOB INPUT PERSNL IF DEPT = 911 PRINT PAY-RPT END-IF * Conceptual post-expansion fragment FILE PERSNL FB(150 1800) EMPNAME 17 8 A EMP# 9 5 N DEPT 98 3 N GROSS 94 4 P 2 JOB INPUT PERSNL IF DEPT = 911 PRINT PAY-RPT END-IF
Compile listings vary by installation, but macro-aware listings show which invocations expanded, sometimes repeating generated lines with sequence numbers for error correlation. When error messages cite statement 000045, scroll the listing to that line in the post-expansion view—often the bug is a substituted token producing invalid syntax, not your original JOB logic.
| Option / practice | Effect on expansion visibility |
|---|---|
| Default macro listing | Shows expanded statements for debugging |
| LIST NOMACROS | Omits expansion detail—smaller listings |
| Full list during macro development | Verify every & substitution |
| Compare before/after library change | Diff expansion output in change review |
Large programs invoking many layout macros generate listings thousands of lines long. Production compile procedures often specify LIST NOMACROS on the compile PARM to archive slimmer output. Turn NOMACROS off when diagnosing parameter errors—without expansion text you only see the percent line and cryptic downstream syntax errors.
1PARM='LIST NOMACROS'
A macro body may contain %OTHERMAC invocations. Preprocessor typically expands inner macros first so outer & substitutions see resolved text or inner-generated lines depending on facility rules. Deep nesting increases compile cost; flatten occasionally by merging stable inner macros into outer bodies after review.
1234MACRO %STD-HEADER LINE 01 DEPT EMPNAME MEND
Actual parameter included special character illegal in identifiers—listing shows DEFINE with bad name. Fix invocation quoting or macro body literal placement.
Keyword default changed or wrong RECLEN passed—compare expansion listing to data dictionary. Not a runtime bug; regenerated source carries wrong numbers until recompile with corrected invocation or macro default.
Preprocessor error before compile—positional-count expects three values, invocation supplied two. Error references macro invocation line in pre-expansion source.
Expanded code is fixed in the load module until next compile. Changing a macro library member does not affect already-linked programs. Operations teams must track which load modules were built against which macro library level—parallel to copybook level tracking in COBOL shops.
The compile process page places preprocessor expansion before syntactic and semantic analysis. Macro expansion errors surface in preprocessor or compiler phases depending on failure type. Debugging overview in the next section covers broader listing interpretation including non-macro errors.
Expansion is like a printer copying a stencil. You hold up the stencil (%MACRO), the printer sprays ink through the holes (arguments), and a full picture appears on the paper (your program). NOMACROS is telling the printer not to show the stencil outline in the instruction manual—fine when you trust the stencil, bad when the picture looks wrong and you need to see which hole was blocked.
1. Macro expansion happens during:
2. LIST NOMACROS on compile PARM:
3. When expansion produces invalid DEFINE syntax, compile fails on:
4. To debug wrong field offsets after macro change, compare:
5. Nested macro means: