Parametric Programming in CNC: Why It's the Hardest G-Code to Verify — and How to Do It Right
Parametric programming is the point where G-code stops being a list of instructions and starts being a program in the full computational sense of the word.
Variables. Arithmetic. Conditional logic. Loops. Jumps. The ability to write a single program that behaves differently depending on the part being machined, the tool in the spindle, or the value stored in a register on the controller.
For experienced CNC programmers, parametric programming — known as Fanuc Custom Macro B on Fanuc and Haas controllers, and as parametric programming or R-parameters on Siemens — is one of the most powerful tools available. It eliminates repetitive programming for families of parts. It enables custom canned cycles that the CAM system cannot generate. It allows logic-driven automation directly in the NC program, without external software.
It is also the category of G-code that is most difficult to verify before it runs on the machine.
This article explains why, what can go wrong, and how to validate parametric programs with the same certainty you would apply to any other NC code.
What Parametric Programming Is — and Why Shops Use It
In standard G-code, every value in every block is fixed at the time the program is written. X50.000 means exactly X50.000. F200 means exactly 200mm per minute. The program does exactly what the programmer wrote, every time, with no variation.
Parametric programming replaces fixed values with variables that are assigned and evaluated at runtime — when the program is actually executing on the controller.
On Fanuc and Haas controllers, variables are designated with the # symbol:
#1 = 50.000 (assign the value 50 to variable #1)
G01 X[#1] F200 (move to X50 - but #1 could be anything)This single change — replacing a fixed coordinate with a variable — makes the program's behavior dependent on what #1 contains at the moment the block executes. That value might be passed in from a calling program, calculated from other variables, read from a system register, or changed by a conditional branch earlier in the program.
The practical applications are significant:
- Families of parts. A bolt circle macro called with different diameter, number of holes, and start angle arguments produces a correctly spaced hole pattern for any combination of those parameters — from a single program. The same macro that drills a 6-hole pattern on a 100mm bolt circle drills a 12-hole pattern on a 200mm bolt circle with no reprogramming.
- Custom canned cycles. A shop that machines the same pocket geometry with minor dimensional variations across many parts can write a single parametric routine that accepts depth, width, length, and corner radius as arguments and generates the complete toolpath — including entry moves, finishing passes, and retract — from those four values. The CAM system is bypassed entirely for that geometry.
- Adaptive logic. A program can read system variables — the current tool length offset, the active work coordinate, the spindle load — and adjust its behavior based on what it finds. A macro can check whether the correct tool is loaded before beginning an operation, generate a custom alarm if it is not, and stop the program safely rather than machining with the wrong tool.
- Automated serialization and logging. A parametric program can increment a part counter stored in a persistent variable register, write the current part number into a comment block, or log production data without operator intervention.
Why Parametric Programs Are the Hardest G-Code to Verify
The power of parametric programming comes from exactly the property that makes it difficult to verify: the program's behavior cannot be determined by reading the code.
In standard G-code, reading the program tells you what will happen. The sequence of moves is fixed. You can trace through it manually, read it in an editor, or look at a backplot and know what the machine will do.
In parametric G-code, the sequence of moves depends on the values of variables at runtime. A WHILE loop executes its body a number of times determined by a variable. An IF/THEN/GOTO branch skips or executes blocks depending on a condition. A coordinate in a motion block is a calculated expression that produces a different value every iteration.
You cannot know what a parametric program will do by reading it. You can only know what it will do by executing it — with specific variable values, on a specific controller, in a specific machine state.
This creates a verification problem that does not exist for standard G-code:
- The CAM simulation does not execute macro logic. CAM systems generate parametric programs in limited contexts, and their built-in simulators almost universally simulate the geometric output of the toolpath rather than executing the G-code. A Fusion 360 simulation of a program that contains macro calls shows the intended toolpath geometry. It does not execute the macro variables, evaluate the conditional logic, or follow the GOTO branches. If the macro has a logic error — a condition that evaluates incorrectly for a specific input, a WHILE loop that does not exit under certain parameter combinations, a GOTO that jumps past a G43 activation — the CAM simulation shows nothing wrong.
- The behavior varies by input. A macro that works correctly for the parameter values tested during prove-out may fail for a different part in the same family. A bolt circle macro verified for 6 holes may produce an incorrect angular step for 5 holes if the programmer made an arithmetic error in the angle calculation. The error is invisible until the program runs with that specific input.
- Controller implementation varies. Fanuc Custom Macro B is not identical across all Fanuc controller generations. Haas's implementation of macro B is close to Fanuc but not identical. A parametric program that runs correctly on a Fanuc 30i may behave differently on a Fanuc 0M because certain system variables return different values, certain functions are not supported, or certain conditional expressions are evaluated differently. These differences are invisible in any simulation that does not model the specific controller.
- Errors in parametric programs fail in unpredictable ways. A standard G-code error typically produces a predictable outcome: a wrong position, a bad arc, an alarm. A parametric error can produce any behavior that the incorrect logic generates — including behavior that looks correct for the first few iterations and then fails, or that runs without alarm but produces the wrong geometry, or that enters an infinite loop and locks the controller.
The Most Common Errors in Parametric Programs
Uninitialized Variables
A variable that has never been assigned a value returns a special null state — on Fanuc, this is represented as #0, which evaluates to zero in arithmetic but has different behavior in conditional expressions. A program that reads an uninitialized variable in a coordinate expression positions the axis at zero. A program that reads it in a conditional expression may evaluate the branch incorrectly.
The most common scenario: a parametric program uses a variable as an accumulator in a loop. If the variable retains a value from a previous program run (common variables #100 and above persist between programs on most Fanuc controllers), the loop starts from the wrong initial value and produces an incorrect number of iterations or incorrect position values.
WHILE Loops That Do Not Exit
A WHILE loop continues executing as long as its condition is true. If the loop variable is not correctly incremented inside the loop body, or if the condition is written with the wrong comparison operator, the loop never terminates. On the machine, this manifests as the program running indefinitely with no alarm — the controller is executing the loop body correctly, it just never reaches the exit condition.
(INTENDED: drill 8 holes in a pattern)
#1 = 0
WHILE [#1 LT 8] DO1
G81 X[#1 * 25] Y0 Z-10 R5 F200
(MISSING: #1 = #1 + 1)
END1Without the increment inside the loop body, this program drills at X0 forever. On a machine during prove-out with single block mode active, the operator will catch it after the first iteration. Without single block mode, the machine runs until an E-stop.
GOTO Jumps That Skip Critical Blocks
GOTO transfers execution to a labeled block, skipping everything between the GOTO and the label. If a critical block — a G43 tool length compensation activation, a G80 canned cycle cancellation, a work offset call — exists between the GOTO origin and the destination label, it is skipped.
IF [#1 EQ 1] GOTO 100
G43 H[#TOOL] Z50. (length comp activation - skipped if #1 = 1)
N100 G01 Z-10. F200 (plunges without length compensation active)This program plunges to Z-10 relative to the machine gauge line rather than the tool tip when #1 equals 1. The depth error is the full tool length — typically 100 to 250mm. On a machine, this is a spindle-into-table crash.
In the CAM simulation, the toolpath shows a plunge to Z-10 relative to the workpiece surface — correctly, because the simulation does not follow the GOTO branch logic.
Arithmetic Errors That Accumulate Across Iterations
Parametric programs that calculate positions incrementally — adding an angular step or a linear offset at each loop iteration — accumulate floating-point arithmetic errors across many iterations. A bolt circle program that calculates each hole angle by adding a step to the previous angle accumulates rounding error differently than one that calculates each angle absolutely from the start angle. Over 36 holes, the accumulated error from incremental calculation can be significant enough to produce measurable position error on the last hole relative to the first.
This type of error is invisible in a CAM simulation and invisible to a programmer reading the code — it only appears when the program executes with a specific combination of hole count and spacing that exposes the accumulation.
Conditional Logic That Works for Test Cases but Fails in Production
A conditional branch written to handle two cases may fail for a third case the programmer did not anticipate. A macro written for a family of rectangular pockets handles the length-greater-than-width case and the width-greater-than-length case, but when the part has equal length and width, neither branch executes and the program falls through to the next block — which may be an unrelated operation, a retract, or the program end.
In testing, the macro was always called with length ≠ width. In production, a square pocket reveals the unhandled case.
Controller-Specific Macro Behavior
Haas controllers implement macro B with minor differences from Fanuc that matter in specific contexts:
- The set of available system variables differs. Some Fanuc system variables for reading machine position or tool data have no direct Haas equivalent or return values in different registers.
- The behavior of certain mathematical functions at edge cases (division by zero, SQRT of negative numbers) may differ in how they are handled or alarmed.
- The maximum nesting depth for macro calls and DO loops may differ between controller generations.
A program developed and verified on a Fanuc controller may produce incorrect behavior on a Haas machine running the same code, or vice versa, due to these differences — which are not documented in the program itself and not visible in any simulation that does not model the specific controller.
How to Verify a Parametric Program Before It Runs on the Machine
The only reliable way to verify a parametric program is to execute it — with the actual variable values it will receive in production, against a model that reflects how your specific controller evaluates the logic.
This means a G-code simulator that:
- Executes the macro logic — evaluates WHILE conditions, follows GOTO branches, resolves IF/THEN expressions — not just plots the geometric output
- Uses the actual variable values that will be passed to the macro in production, not assumed or averaged values
- Shows the resulting motion against the full machine model — tool, holder, fixture, workpiece — so that any position error from logic faults is immediately visible as incorrect geometry or a collision
- Reflects the controller's specific macro implementation, including system variable behavior and evaluation rules
This is fundamentally different from a CAM backplot or a toolpath viewer. It is execution of the parametric logic, not visualization of an assumed output.
The practical workflow for parametric program verification:
Before the program runs on the machine, it should be simulated with each distinct set of input values that will be used in production. For a family-of-parts macro, this means simulating with the smallest part, the largest part, and any edge-case dimensions that exercise the conditional branches. For a custom canned cycle, this means simulating with the parameter values for each part where the cycle will be called.
Problems found in simulation — a GOTO that skips compensation, a loop that does not exit, an arithmetic error visible as incorrect geometry — are fixed in the editor before the program goes to the machine. The fix is verified in the same simulation session by resuming from the corrected point.
Eureka 3X Pro: G-Code Simulation That Handles Parametric Logic
Eureka 3X Pro executes the actual posted G-code — including parametric logic — against a digital twin of your 3-axis CNC machine.
When a program contains macro variables, WHILE loops, IF/THEN/GOTO branches, or G65 macro calls, Eureka executes that logic as the controller would. The simulation shows the actual motion the parametric program produces for the specific variable values in use — not an assumed geometric output, not a toolpath that ignores the macro structure.
This means:
- A GOTO that skips a G43 block is visible as a Z-axis position error in the simulation before it becomes a crash on the machine
- A WHILE loop that does not exit is caught in the simulation before it locks the controller
- An arithmetic error that accumulates across 36 hole positions is visible as geometric deviation in the simulated toolpath
- A conditional branch that fails for a specific parameter combination shows the incorrect motion for that combination before the part is machined
When the simulation finds a problem, you pause, edit the NC file in the integrated editor, and resume from the same point. The corrected program is the one that goes to the machine.
The Fundamental Principle
Standard G-code is a script. You can read a script and know what it will do.
Parametric G-code is a program. You cannot read a program and know what it will do for every possible input. You have to execute it.
The question is where you execute it. On the machine — using machine time, exposing the machine to the risk of a logic error made visible for the first time in production — or in simulation, before the program touches the machine, where every logic error is a data point rather than a crash.
Run every G-code program risk-free — before it touches your machine.
Start your 30-day free trial of Eureka 3X Pro →