top | item 6290141

What is a magic number, and why is it bad?

31 points| carlosgg | 12 years ago |stackoverflow.com

32 comments

order
[+] bicx|12 years ago|reply
I just have a Numbers class I import into all my projects:

public final static int ZERO = 0; public final static int ONE = 1; public final static int TWO = 2; public final static int THREE = 3; public final static int FOUR = 4; ....

(jk)

[+] arethuza|12 years ago|reply
I've seen a project that defined string constants like:

   public static String HTTP = "http";
   public static String COLON = ":";
   public static String SLASH = "/";
with code that looked like:

   url = HTTP + COLON + SLASH + SLASH + ....
[NB I am NOT joking]
[+] acheron|12 years ago|reply
I'm glad you are kidding about this, but thedailywtf.com is full of examples of people who weren't.
[+] pivnicek|12 years ago|reply
What really is the difference you are achieving? Are you going to redefine zero?
[+] radio4fan|12 years ago|reply
The primary purpose of the DATA statement is to give names to constants; instead of referring to pi as 3.141592653589793 at every appearance, the variable PI can be given that value with a DATA statement and used instead of the longer form of the constant.

This also simplifies modifying the program, should the value of pi change.

-- Early FORTRAN manual for Xerox Computers

[+] dllthomas|12 years ago|reply
No one seems to be mentioning another use of the phrase "magic number" which isn't bad at all - numbers put in files to mark the file type. 0xCAFEBABE in java class files, for instance.
[+] greenyoda|12 years ago|reply
Unix even has "man 5 magic", which describes the format of the magic numbers file that the "file" command uses to determine the type of a file (executable, object code, shell script, etc.) from its first few characters.

My personal favorite magic numbers are the values that debuggers use to fill uninitialized memory, like 0xDEADBEEF, 0xBAADF00D, etc.

Wikipedia has a good article on magic numbers:

https://en.wikipedia.org/wiki/Magic_number_(programming)

[+] bluedino|12 years ago|reply
That is about the worst top-rated answer I've seen in a while on SO.
[+] simias|12 years ago|reply
Agreed.

In my opinion there are two kinds of magic numbers:

* the first kind is the one most answers describe: an arbitrary number used in various places that may change at any moment. The size of a buffer for instance.

* the second kind are numbers that represent something very specific but not immediately obvious when reading the code: for instance in a device driver "read_register(base + DEVICE_STATUS)" is much clearer than "read_register(base + 0x3c)". In this case naming the magic number is useful even if it's used only once in the code. It acts as a comment basically.

I'd also add that sometimes adding too many levels of indirection is a bad thing, and in the (currently) top voted answer I prefer the original over the "fixed" version. Either you do the right thing and make MAX_PASSWORD_SIZE something meaningful or you might as well write "if (password.length() > 7)". It's clear, non ambiguous and (in the example) not reused anywhere. Defining a macro for that just hides poor code and forces me to go look for the definition in order to understand what's going on (while debugging for instance).

[+] praptak|12 years ago|reply
Agreed. All of the top 3 answers focus on the numbers being directly used in code which is not the real reason why magic numbers cause problems.

They are bad because of not being explained. A number directly used in code is not magic if it is properly commented. Granted, explaining it by making it a named constant is very often better (reusability), but a literal number that is merely commented is not "magic".

[+] timje1|12 years ago|reply
I find these a lot with CSS - banishing them seem to be a major goal of LESS, SASS etc.

They also seem to crop up too often in JS / JQuery, particularly the manipulation of CSS.. where do you folks tend to find them?

[+] dsego|12 years ago|reply
Also, it can be a good idea to yank out all of those into a separate config file. Although, it destroys locality, so it depends on the use case I guess.
[+] qu4z-2|12 years ago|reply
I wouldn't move it into a config file unless you're also testing the code works correctly with different values. Otherwise it's just asking for trouble.
[+] prezjordan|12 years ago|reply
New term added to my vocabulary - thanks for sharing!
[+] tzs|12 years ago|reply
I just call any constants that slip into my code "advanced technology numbers" if someone gives me a hard time about them.
[+] a3voices|12 years ago|reply
Caring about magic numbers is a distraction from real problems, such as getting your software working.
[+] crpatino|12 years ago|reply
Not if you care about maintainability.

I was about to go into a rant about that moron that named its variables after Starwars characters and then left for a better paying gig, leaving his unmaintainable mess for others to care about, but it would be unfair for me to project my own traumas into you. Besides... it was 2007, so I better learn to let go.

Instead, I am going to say that getting your software working is one important goal, perhaps the most important goal because by doing that you get the money and the social capital that let you keep going and accomplish the other goals, but it is not the only goal.

Other goals, such as maintainability, are important too, and they come with their own sets of requirements and constrains, often conflicting with those of other goals. If you want to call yourself a professional, you must recognize those conflicts and make deliberate tradeoffs based on local conditions, and never gratuitously undermine any set of goals just for the sake of it.

Or you can make a whole career out of bluffing and waving the "get shit done" mantra. Never keeping the same job long enough for the consequences of your own poor decisions to come back and bite you in the ass.

[+] sophacles|12 years ago|reply
It isn't hard (actually it's pretty easy) to get in the habit of replacing magic numbers with named constants immediately. Any time you hardcode a number just name it instead, and on the line immediately above it define the constant with a "TODO: refactor to the right place" comment. That way when you're done with the current creative focus, you can go back and put it right. This fixing is great for boring meetings, warmup/rezoning time, and so on. Alternately just keep a bookmark to the #defines in your editor and go drop it in the right place immediately.

Doing this makes life convenient because magic numbers often turn out to be real problems - did you typo the number somewhere? Did you forget to update the magic in one spot? These bugs waste more time in hunts than they cost in "do it right immediately".

[+] jneal|12 years ago|reply
Maybe...But caring about magic numbers can also keep your software working properly.
[+] benjaminwootton|12 years ago|reply
Refactoring out magic numbers (and magic strings!) is one of the easiest refactorings you can do.

Not putting in the effort to pull these out shows a complete disregard for code quality and maintenance.

[+] timje1|12 years ago|reply
Once the software's working, and has been for several years, and it has become unmaintainable because lax guidelines let this stuff through, this sort of thing becomes your real problem.
[+] bitwize|12 years ago|reply
I once worked with a guy who thought like this. His work was a morass of hundreds-of-lines-long VB methods. And when it stopped working, it stopped working hard, and I had to pick up the pieces.

Good programming practices are not a distraction from getting it working. They're essential to keeping it working, even in the face of changing requirements and unanticipated circumstances.

[+] SanjayUttam|12 years ago|reply
Because doing so is one of the many measures you can take to ensure your software is (and stays) easily maintainable. Getting your SW working is only really one stage of a product life cycle.