Logical Operators in CNC Macros: IF, WHILE, and GOTO Guide
Master Fanuc, Siemens, and Mitsubishi CNC macro logical operators. Prevent crashes by configuring parameters, nested loops, and look-ahead buffers safely.
Introduction
An unincremented variable or an untimely condition check in a CNC macro program will drive a heavy cutting tool or lathe turret directly into a vise jaw, a secured workpiece clamp, or a rotating chuck at full feedrate. When a machine becomes trapped in an infinite loop due to a missing counter increment, the controller continuously processes the same motion block without advancing. Similarly, if look-ahead evaluation is not properly synchronized, the interpreter evaluates branching logic prematurely, causing the tool to skip vital retraction paths. These logic errors lead directly to violent hard collisions, destroyed workpieces, damaged spindles, and costly machine downtime. Implementing precise conditional logic and loop controls is the primary defense against such catastrophic program failures.
Technical Summary
| Technical Attribute | Details |
|---|---|
| Command Code | IF, WHILE, GOTO, DO, END, ELSE, ENDIF, GOTOF, GOTOB, GOTOC, REPEAT, UNTIL, FOR, LOOP, CASE |
| Modal Group / Modality | Macro Control Statements (non-modal) |
| Brands | Fanuc, Siemens, Mitsubishi |
| Critical Parameters | Fanuc: 6000#1 (MGO), 6000#4 (HGO), 6006#0 (MLG); Siemens: $MC_EXTERN_FUNCTION_MASK bit 3; Mitsubishi: #8101 (MACRO SINGLE), #6452 bit 6 |
| Main Constraint | Fanuc: Max 3 DO loops per level, 5-level bracket nesting limit; Siemens: 808D restricted to 11 nesting levels; Mitsubishi: Max 10 IF and 27 WHILE nesting levels, Tape mode jumps prohibited |
Quick Read
- Verify Loop Increments: Always write and double-check math counters (e.g.,
#1 = #1 + 1) insideWHILEloops to avoid infinite execution and hard crashes. - Synchronize the Look-Ahead: Insert a preprocessing stop (
STOPRE) before conditionalIFbranches in Siemens programs to prevent early evaluation of dynamic variables. - Avoid Float Equality Checks: Evaluate decimal variables using absolute tolerances (e.g.,
[ABS[#10 - #20] LT 0.01]) instead of strict equal (EQ) checks to prevent floating-point calculation errors. - Observe Nesting Limitations: Maintain nesting within controller limits (max 3 loop levels on Fanuc, 11 subprograms on Siemens 808D, and 10 IF / 27 DO levels on Mitsubishi).
- Select the Right Execution Mode: Avoid running macro looping or branching statements in Tape/DNC mode on Mitsubishi systems to prevent an immediate P295 alarm and program termination.
- Utilize High-Speed GOTO Caching: Enable Fanuc parameters 6000#1 (MGO) and 6000#4 (HGO) to optimize branching performance and reduce loop execution delay.
Basic Concepts
The practical programming effect of logical macro operators is the total transformation of rigid, linear G-code into dynamic, decision-making software. Using WHILE/DO loops, programmers can write a highly condensed mathematical routine to execute repetitive physical tasks—such as deep-hole pecking, grid drilling, or spiral milling—in just a few blocks rather than thousands of lines of G-code. By substituting fixed geometric movements with variable iteration structures, a single master program can adapt to different dimensions, paths, and patterns.
Simultaneously, conditional branching statements allow the CNC machine to autonomously evaluate physical conditions on the shop floor. For example, a macro program can read a touch probe's skip signal position or query a tool wear offset system variable to check if a component is within tolerance. The control can then logically evaluate this data and instantly alter its own toolpath to bypass finishing passes, trigger compensating coordinate shifts, or abort the cycle if a tool is broken.
To ensure safe and reliable operation of these logical structures, programmers must verify that loop boundaries are never crossed and that conditional parameters are correctly formatted. Incorrect syntax, nested brackets exceeding control limits, or unpaired loop markers will be caught by the CNC's internal parser. When this occurs, the controller halts automatic execution and displays an alarm message, protecting the machine tool before physical movement can begin.
Command Structure and Syntax
Macro programs control execution flow through three main structures: unconditional jumps, conditional branches, and iterative loops. Unconditional jumps use the GOTO command to force the interpreter to jump directly to a specific block number, bypassing all intervening lines of code. Conditional branches combine a logical comparison inside brackets with a GOTO jump or a THEN statement, executing the redirection only when the evaluated relation is true. Iterative loops use WHILE statements to repeatedly run a sub-block of code between DO and END markers as long as the conditional criteria remain fulfilled.
Each control brand implements specific syntax formats for these commands. Fanuc and Mitsubishi follow the Custom Macro B standard where variables and operators are enclosed in square brackets. Siemens utilizes structured, high-level commands similar to modern computer programming languages, including native IF-ELSE-ENDIF, FOR, and REPEAT-UNTIL loops. Regardless of the control tier, proper syntax spacing, bracket pairing, and loop identifiers are required to ensure the interpreter compiles the program without halting.
; Fanuc Custom Macro B Syntax
GOTO 100;
IF [#100 GT 5.0] GOTO 200;
IF [#101 EQ 1.0] THEN #102 = 1.5;
WHILE [#1 LT 10.0] DO 1;
...
END 1;
; Siemens SINUMERIK High-Level Syntax
GOTO LABEL1
IF R10 > 5 GOTOF LABEL2
IF R10 == 1.0 ELSE ... ENDIF
WHILE R1 < 10.0
...
ENDWHILE
; Mitsubishi Logic Syntax
GOTO 100;
IF [#100 GT 5.0] GOTO 200;
IF [#101 EQ 1.0] THEN;
...
ELSE;
...
ENDIF;
WHILE [#1 LT 10.0] DO1;
...
END1;
| Parameter / Variable | Brand | Description |
|---|---|---|
6000#1 (MGO) | Fanuc | High-speed GOTO branching behavior. 0: standard; 1: high-speed cache search (up to 20 blocks). |
6000#4 (HGO) | Fanuc | Localized branch caching. 1: caches 30 blocks before jump or 10 saved by previous search. |
6006#0 (MLG) | Fanuc | Enables boolean logical operations (AND, OR, etc.) inside conditional statements. |
$MC_EXTERN_FUNCTION_MASK | Siemens | Bit 3 dictates whether Siemens-specific check structures are processed natively in ISO dialect mode. |
#8101 (MACRO SINGLE) | Mitsubishi | Macro processing mode. 0: background batch; 1: block-by-block concurrently. |
#6452 (bit 6) | Mitsubishi | Branch destination validation. 1: checks labels; 0: missing labels trigger bus error. |
Brand-Specific Applications
Fanuc
Fanuc Custom Macro B utilizes logical operators and control statements to execute conditional branching and iteration. Relational operators like EQ, NE, GT, LT, GE, and LE are evaluated inside brackets. Parameters 6000#1 and 6000#4 dictate look-ahead caching behavior to optimize GOTO searches.
Below is a typical G-code structure for conditional branching and loop controls on Fanuc systems:
IF [#100 GT 10.0] GOTO 500;
WHILE [#1 LT 5.0] DO 1;
...
END 1;
| Attribute Type | Details |
|---|---|
| Parameters | 6000#1 (MGO) for GOTO speed cache, 6000#4 (HGO) for local caching, and 6006#0 (MLG) for boolean operations. |
| Alarms | Alarm 124 (Missing END statement), Alarm 126 (Illegal loop number outside 1-3), and Alarm 128 (Missing sequence number). |
| Versions | Custom Macro B permits single THEN lines. Modern series support nested IF-THEN-ELSE-ENDIF and CASE statements. |
Warning: Forgetting to increment the loop control variable will lock the controller in an infinite execution cycle, resulting in uncommanded motion and a hard collision with workholding clamps.
Siemens
Siemens Sinumerik controls embed PC-style structured language elements directly into standard G-code. Conditional jump statements like GOTOF and GOTOB direct program flow. Synchronization is maintained using the STOPRE command to control look-ahead processing.
The following is a representation of high-level Siemens G-code control structures:
IF (R10 < 50) AND ($AA_IM[X] >= 17.5) GOTOF LABEL_A
WHILE $AA_IW[DRILL_AXIS] > -10
...
ENDWHILE
| Attribute Type | Details |
|---|---|
| Parameters | $MC_EXTERN_FUNCTION_MASK bit 3 for ISO dialect processing translation settings. |
| Alarms | Alarm 14080 (Jump destination label not found) and Alarm 14000 (External jump destination outside buffer limits). |
| Versions | 808D family restricts nesting to 11 levels, whereas 840D sl and SINUMERIK ONE support up to 16 nesting levels. |
Warning: Failing to place a STOPRE preprocessing stop before checking real-time machine states can lead to premature look-ahead evaluations, resulting in tools plunging into clamps or vise jaws.
Mitsubishi
Mitsubishi CNCs offer advanced logical branching with nested IF-THEN-ELSE structures and WHILE loops. Parameter #8101 configures whether macros run in background batch or block-by-block. Parameter #6452 validates destination labels.
Here is an example of conditional branching and absolute value comparisons on Mitsubishi controls:
IF [ABS [#10 - #20] LT 0.01] THEN #120 = 10;
WHILE [#101 LT #2] DO1;
...
END1;
| Attribute Type | Details |
|---|---|
| Parameters | #8101 (MACRO SINGLE) control mode, #1754 (processing speed), #1259 (execution optimization), and #6452 bit 6 (label checking). |
| Alarms | P288 (IF nesting excess over 10 levels), P293 (Loop nesting over 27 levels), and P295 (WHILE/GOTO executed in Tape mode). |
| Versions | M800VW/M80VW Series allows calling macros stored on the display unit built-in disk using G65/G66, unlike non-VW models. |
Warning: Running GOTO or WHILE statements in Tape mode will instantly trigger a P295 alarm, halting machine operations mid-cut.
Brand Comparison
| Feature / Topic | Fanuc | Siemens | Mitsubishi |
|---|---|---|---|
| Loop Nesting Limit | Max 3 DO-END loops (DO 1, DO 2, DO 3) per macro level. | 808D limits macro nesting to 11 levels. 840D sl / ONE permits up to 16 levels (expandable to 18 with ASUBs). | WHILE-DO loops nested up to 27 levels deep. Loop identifiers range from 1 to 127. |
| Structured Syntax | Archaic IF-GOTO and IF-THEN. Newer series support nested IF-THEN-ELSE-ENDIF via reserved words. | Native PC-style control structures (IF-ELSE-ENDIF, WHILE, FOR, LOOP). | Natively supports IF-THEN-ELSE-ENDIF directly in G-code, nested up to 10 levels deep. |
| Search Caching | Look-ahead parameters 6000#1 (MGO) and 6000#4 (HGO) avoid linear program scanning for jumps. | Alarm-suppressed jump command GOTOC suppresses Alarm 14080 if label is missing. | Parameter #8101 (MACRO SINGLE) switches background logic processing ON/OFF. |
| Custom Alarm Integration | Intertwines logic with variable #3000; display format globally dictated by parameter 6008#1 (MCA). | Command SETAL raises user alarms (60000 to 69999). | Program error alarm codes (P288, P289, P293, P294, P295) halt the machine on logic syntax/nesting errors. |
| Condition Evaluation Rules | Done in Custom Macro B; look-ahead buffer might execute variables ahead of physical motion. | Programmers must use preprocessing stop command STOPRE on a line prior to dynamic condition checks. | Programmers must evaluate decimals with safety tolerances using the ABS function to prevent floating-point mismatch. |
Technical Analysis
Analytical comparison of these three CNC platforms reveals distinct philosophies in logic execution, syntax safety, and processing efficiency. Fanuc adopts a highly optimized but structurally rigid approach. Its loop nesting is strictly limited to three levels, preventing buffer overloads, while GOTO search performance is maintained using specific hardware look-ahead caching. However, this rigid structure makes writing complex, readable programs challenging without resorting to deep numeric variable indexing.
In contrast, Siemens focuses on readable, PC-style high-level programming. By embedding nested IF-ELSE-ENDIF, FOR, and REPEAT-UNTIL structures natively, it eliminates the need for obscure variable mappings. Siemens also provides specialized jump commands like GOTOC that suppress destination alarms, allowing programs to skip missing optional blocks safely. The main risk is interpreter look-ahead execution, which requires the programmer to explicitly write STOPRE blocks to synchronize real-time variables before evaluating logic.
Mitsubishi represents a middle ground, blending ISO Custom Macro B syntax with modern high-level execution. It allows an immense nesting depth of up to 27 loop levels and 10 IF levels, giving programmers vast scale. Mitsubishi also offers unique diagnostic flexibility through parameter #8101 (MACRO SINGLE), allowing operators to run macros block-by-block for dry runs or in the background for production speed. However, it requires careful decimal comparisons using the ABS function to bypass floating-point inequalities that cause tool crashes.
Program Examples
Fanuc Program Example: Grid Drilling Cycle
; Fanuc Custom Macro B Grid Drilling
#100 = 0 (COLUMN COUNTER)
#101 = 3 (TOTAL COLUMNS)
#102 = 50.0 (COLUMN SPACING IN MM)
WHILE [#100 LT #101] DO 1;
#103 = 0 (ROW COUNTER)
#104 = 4 (TOTAL ROWS)
#105 = 40.0 (ROW SPACING IN MM)
WHILE [#103 LT #104] DO 2;
G90 G00 X[#100 * #102] Y[#103 * #105];
G81 Z-15.0 R2.0 F150.0;
G80;
#103 = #103 + 1 (INCREMENT ROW);
END 2;
#100 = #100 + 1 (INCREMENT COLUMN);
END 1;
M30;
dry run
During a dry run, the controller starts with #100 = 0 and #101 = 3. The outer loop condition #100 LT #101 evaluates to true, entering Loop 1. Inside, #103 is reset to 0. The inner loop condition #103 LT #104 (0 < 4) evaluates to true, entering Loop 2. The machine moves to X0.0 Y0.0 and executes a G81 drilling cycle to Z-15.0. Loop variable #103 increments to 1. The inner loop repeats for Y40.0, Y80.0, and Y120.0. When #103 reaches 4, Loop 2 terminates. #100 increments to 1, moving the machine to X50.0. The process repeats for columns 1 and 2. When #100 becomes 3, Loop 1 evaluates to false, and the program ends with M30.
Siemens Program Example: Tool Checking and Safe Path Rotation
; Siemens Sinumerik Tool Check and Safe Retract
R10 = $TC_MPPC1[1] ; Read active tool wear value
STOPRE ; Force preprocessing stop to sync look-ahead
IF R10 > 0.25 GOTOF ALARM_RETRCT
; Standard Path
G00 X100.0 Z50.0
M30
ALARM_RETRCT:
GOTOC SAFE_HOME
SAFE_HOME:
G00 G53 Z0.0 D0 ; Safe Z retraction
SETAL(60100) ; Trigger custom tool wear alarm
M30
dry run
The interpreter reads the active tool wear value into R10. The STOPRE block halts the LookAhead buffer, ensuring the wear value is fully read before the condition is checked. If R10 exceeds 0.25 mm, the IF condition evaluates to true, and the program jumps forward (GOTOF) to ALARM_RETRCT. The code then initiates a GOTOC jump to SAFE_HOME. If the SAFE_HOME label exists, it executes the safe Z-axis retraction to machine reference (G53 Z0.0) and disables tool offsets (D0). The SETAL(60100) instruction executes, halting machine movement and displaying user alarm 60100 on the screen.
Mitsubishi Program Example: Safe Parametric Pecking Loop
; Mitsubishi Safe Pecking Cycle with ABS Tolerance
#100 = -50.0 (TARGET DEPTH Z)
#101 = 0.0 (CURRENT Z DEPTH)
#102 = -10.0 (PECK INCREMENT)
#103 = 0.01 (SAFETY TOLERANCE)
WHILE [ABS[#101 - #100] GT #103] DO1;
#101 = #101 + #102;
IF [#101 LT #100] THEN #101 = #100;
G00 Z[#101 + 2.0];
G01 Z#101 F100.0;
G00 Z2.0; (RETRACT TO CLEARANCE)
END1;
M30;
dry run
The program sets target depth #100 to -50.0 and current depth #101 to 0.0. Peck size is #102 = -10.0. The WHILE loop checks if the absolute difference between #101 and #100 is greater than tolerance #103. The first check evaluates ABS[0.0 - (-50.0)] which is 50.0. Since 50.0 > 0.01, the loop enters. #101 is updated to -10.0. The IF-THEN verifies #101 has not overrun #100. The tool moves to Z-8.0, feeds to Z-10.0, and retracts to Z2.0 clearance. The loop repeats, pecking to Z-20.0, Z-30.0, Z-40.0, and Z-50.0. On the final iteration, the difference is 0.0, which is not greater than #103, so the loop terminates and the program exits via M30.
Error Analysis
| Brand | Alarm Code | Trigger Condition | Operator Symptom | Root Cause / Fix |
|---|---|---|---|---|
| Fanuc | 124 / PS1124 | DO - END nesting does not correspond 1:1. | Cycle halts immediately before executing the loop. Screen shows "MISSING END STATEMENT". | Ensure every DO statement has a matching END statement with the same identifier in the program. |
| Fanuc | 126 | DO identifier m is outside the range 1 to 3. | CNC enters alarm state on block execution. Screen shows "ILLEGAL LOOP NUMBER". | Modify the loop block to use DO identifiers strictly limited to DO 1, DO 2, or DO 3. |
| Fanuc | 128 / PS1128 | GOTO destination sequence number not found or out of range. | Execution stops at the GOTO command. Screen shows "SEQUENCE NUMBER OUT OF RANGE". | Verify that the target N sequence number exists and is within 1 to 99999999. |
| Siemens | 14080 | Jump destination label or block number missing in the active program level. | Interpreter stop occurs immediately. Screen shows "Jump destination not found". | Check the spelling of the label or block number. Ensure the target exists in the active program level. |
| Siemens | 14000 | External subprogram jump destination falls outside the reload buffer. | Execution stops mid-program during external file read. Screen shows memory buffer error. | Ensure the jump target (like a GOTOB or REPEAT label) resides within the post-loading buffer boundary. |
| Mitsubishi | P288 | IF statement nesting depth exceeds the maximum of 10 levels. | Execution halts during program load or macro call. Screen shows "IF EXCESS" alarm. | Restructure the macro logic to flatten the nested conditional tree to 10 levels or fewer. |
| Mitsubishi | P293 | WHILE-DO loop nesting level exceeds 27 levels. | Interpreter halts execution immediately. Screen shows "DO-END nesting over". | Redesign the program loops to ensure nesting depth does not exceed the 27-level hardware limit. |
| Mitsubishi | P295 | WHILE or GOTO command executed during Tape operation mode. | The CNC halts mid-cut during tape feed. Screen shows "WHILE/GOTO in tape" alarm. | Load the macro program into the CNC's internal memory and execute in Memory mode rather than DNC/Tape mode. |
Application Note
A tool turret crash into a chuck barrier or a workholding clamp occurs when decimal numbers are compared using exact operators on Mitsubishi controls. Infinitesimal floating-point calculation errors in variable evaluations can cause an IF [#10 EQ #20] condition to evaluate as false even when the numbers are mathematically equal. To prevent this, the programmer must use the absolute value function to check the difference against a safety tolerance, such as IF [ABS [#10 - #20] LT 0.01]. Without this check, the CNC may bypass a critical retraction branch, leading to a hard collision. Similarly, on Siemens controls, omitting the STOPRE preprocessing stop before a conditional jump allows the look-ahead buffer to evaluate dynamic states using outdated data. This results in the tool plunging into a secured vise jaw or striking a rigid compensating chuck during a G331 tapping cycle, triggering clamping timeout alarms. For Fanuc systems, executing unconditional jumps without caching parameters like 6000#1 (MGO) or 6000#4 (HGO) forces the controller to scan the program line-by-line, causing significant cycle time delays during high-speed machining.
Related Command Network
- g65-custom-macro-b: Calls custom macros containing conditional loop logic with arguments passed to local variables.
- writing-and-calling-subprograms: Implements nested subroutines that can be repetitively executed using logical counter increments.
- r-parameter-programming: Utilizes arithmetic variables on Siemens systems to pass coordinates and feedrates to structured loops.
- STOPRE: Halts the look-ahead interpreter buffer on Siemens controls to ensure dynamic machine states are fully evaluated before conditional jumps are executed.
Conclusion
Implementing conditional macro logic transforms static toolpaths into responsive, self-correcting programs that protect machine hardware. The key to reliable operation lies in syncing the controller's look-ahead buffer, checking decimal comparisons using small tolerances, and enforcing strict loop nesting boundaries. Regularly auditing macro syntax and verifying parameter settings for jump caches ensures high-speed, crash-free execution on the shop floor.
Frequently Asked Questions
Why does my macro cause an infinite loop on a Fanuc control?
An infinite loop occurs when the conditional expression in a WHILE statement never evaluates to false. This is typically caused by omitting the counter increment variable (such as #1 = #1 + 1) inside the DO-END loop. To resolve this, always verify that your loop control variable increases with every iteration, and use single-block execution during a dry run to check the loop's termination behavior before cutting metal.
What is the difference between GOTO and GOTOC on Siemens systems?
While GOTO immediately halts program execution and throws alarm 14080 if the destination label is missing, GOTOC suppresses the alarm and allows the program to continue executing the next block. This provides a safe, flexible method for creating optional program branches. Programmers should use GOTOC for optional probing or measurement cycles, while reserving standard GOTO for critical safety redirection paths.
Why does my Mitsubishi control trigger a P295 alarm?
The P295 program error alarm is triggered when a GOTO jump or a WHILE loop is executed while the machine is running in Tape mode. Mitsubishi controls restrict logic-branching and looping statements to Memory mode because Tape mode executes blocks sequentially from an external device without buffering the entire logic path. To fix this, transfer the macro file directly to the CNC's internal solid-state memory and run the program in Memory mode.
Still not resolved?
Ask our AI assistant about this topic in natural language. Grounded in verified sources, no hallucinations.

- CNC CARE Co-Founder (May 2025 - Present)
- Mitsubishi Electric NC Sales & Service Section Manager (2008 - 2025)
- Reis CNC Service Engineer (2003 - 2005)
- Ören Kalıp CNC Mold Line Team Leader (1999 - 2002)
With over 25 years of experience working in all areas of the CNC machine industry, I continue my activities as a co-founder of CNC CARE, where we offer brand-independent consulting, engineering, and original spare parts services.
Related Articles
Other articles on this topic
Enabling Fanuc 3D Interference Check: Parameters and Setup
Configure Fanuc 3D Interference Check parameters. Learn how to set parameter 10930#0, troubleshoot Alarm PS0492, and prevent crashes with iHMI solid models.
Configuring Fanuc Custom Macro Enable Parameters (0932 & 8135)
Learn how to configure Fanuc custom macro enable parameters 0932 and 8135, expand common variables, and resolve Alarm 123 on CNC controller boards.
Fanuc Tool Life Management Parameters Configuration Guide
Learn to configure Fanuc tool life management parameters like 6800 and 6810. Prevent crash alarms 156 and 159 to enable unmanned, collision-free CNC machining.
Fanuc Rigid Tapping Optimal Acceleration Parameters Config Guide
Learn how to enable Fanuc optimum torque acceleration for rigid tapping using parameter 11420#0, tune gears 1 to 4, and resolve servo tracking alarm SP0741.