CMake允许纯数字变量名的原因是什么?此类命名引发逻辑问题
Great question—this is one of those quirky CMake behaviors that trips up even experienced users, and it boils down to a combination of historical design choices and CMake's somewhat permissive parsing rules.
First, let's tackle why pure numeric variable names are allowed:
CMake was designed with intentional flexibility in variable naming to accommodate a wide range of user workflows. Unlike many programming languages that require variables to start with a letter or underscore, CMake's parser permits variable names made up of almost any alphanumeric characters (including pure numbers) right out of the box. This was likely a deliberate choice to avoid imposing unnecessary restrictions, especially in early versions where the tool was focused on simplicity and cross-platform adaptability.
Now, the confusing logic issues you're seeing stem directly from how CMake evaluates expressions in if/while blocks. As you noted, these constructs don't require ${} to reference variables—CMake automatically tries to resolve unquoted tokens as variables first, before treating them as literal values. Let's break down your examples:
Example 1: Direct variable vs. literal confusion
set(1 3) set(2 3) if (1 EQUAL 2) MESSAGE( "hi there" ) endif()
When CMake processes the if condition, it doesn't see the 1 and 2 as literal numbers. Instead, it checks if there are variables named 1 and 2, finds their values (both 3), and evaluates 3 EQUAL 3—which is true, hence the unexpected "hi there" message.
Example 2: Indirect variable expansion leading to unexpected resolution
set(1 2) # Later in code or another file: set(var1 1) if (${var1} EQUAL 2) MESSAGE( "hi there" ) endif()
Here, ${var1} expands to the string 1. But again, CMake doesn't treat this expanded 1 as a literal—it resolves it to the variable 1's value (2), turning the condition into 2 EQUAL 2 which evaluates to true. This is especially insidious because the conflict can happen across different files or parts of a project, making it hard to trace.
So what's the fix?
The simplest and most reliable solution is to never use pure numeric variable names—stick to standard naming conventions: start with a letter, use underscores to separate words, and append numbers if needed (e.g., var_1 instead of 1). This eliminates the ambiguity entirely.
If you ever need to ensure a number is treated as a literal in an if condition (and you're worried about accidental variable conflicts), you can explicitly force literal evaluation by using generator expressions like $<0:1> for the number 1, but this is usually overkill—avoiding numeric variable names is the cleaner approach.
内容的提问来源于stack exchange,提问作者Artsiom Chapialiou

