What is a magic number in programming?
By Flavio Copes
Learn what a magic number is in programming: a hard-coded value with no clear meaning, and why you should replace it with a named constant like PIN_ID.
A magic number is a value hard-coded in a program with no explanation of what it means. In some tutorials, books, or videos, you might have seen the term.
When is a number magic? When it has no meaning associated. Unfortunately magicians have nothing to do with it.
It might be an undocumented number passed to a function. Or a number declared in your code, maybe added by a team member, that you don’t really know what it means.
What happens if you change it? No one knows.
It’s up to experimentation to find out.
Why magic numbers are a problem
Take this line:
doSomething(1);
What is 1? A pin number? A mode flag? An ID? You can’t tell without reading the source of doSomething(), or asking whoever wrote the line.
There’s a second problem: duplication. Say 86400 appears in five places in your codebase, because that’s the number of seconds in a day. When you need to change it, you must hunt down every occurrence, and hope you don’t miss one.
Worse: two occurrences of the same number might mean different things. Maybe one of those 86400 is a cache duration, and another is a session timeout. Change them together and you’ve introduced a bug.
The fix: named constants
Declare a constant with a meaningful name, and use that instead of the magic number:
const int PIN_ID = 1;
doSomething(PIN_ID);
This is much better, and self-documenting, compared to:
doSomething(1);
The name explains the intent. And when the value needs to change, you update it in one place:
const int SECONDS_IN_A_DAY = 86400;
Now the number has a single home, and every use points back to it.
Which numbers are fine as-is
Not every literal is magic. 0 and 1 are usually fine in obvious contexts, like initializing a counter or incrementing an index. If the meaning is clear from the surrounding code, a constant adds noise, not clarity.
One pitfall to avoid: name the constant after its meaning, not its value. A constant like TWO holding 2 is useless. If the value ever changes to 3, you have a constant named TWO holding 3. A name like MAX_RETRIES tells you why the number exists.
The same idea applies to strings. A hard-coded "admin" repeated across the codebase is a magic string, and it deserves a constant for the same reasons.
Related posts about tutorial: