[Newbie Question] Magic Number's dangerous?

M

Monique Y. Mudama

But only if the number or string has the same semantic meaning. If
two numbers appear and happen to be the same value, but one could
change independently of the other, it doesn't make sense to
artificially tie them together.

I know, that should fall under the common sense, but as in other
things, common sense isn't as common as it should be.

I remember discovering the following during a code review:

#define ONE 1
#define TWO 2
#define THREE 3
[...]

...all the way to a hundred or so.

I asked the programmer if he thought that any of these values might
need to change one day (no), or if he could tell me what any of them
meant (only by looking at the code where they were used).

Nobody had ever explained to him the *purpose* of using symbolic
constants, just that it was a bad idea to have the values themselves
directly in the code.

/gordon

Eek.

I had to work with code that had some brilliant lines:

#define PKT_TEN 10
#define PKT_FIFTEEN 15
#define PKT_TWNTYTWO 22
#define PKT_TWENTYTHREE 23

Yes, not only did the previous dev hard-code these numbers, he
actually spelled twenty differently in various packet names.

So then I got to go tracing through the code, trying to figure out
what the heck packet 15 did, anyway.
 
M

Monique Y. Mudama

Ahh ok.

Knew the concept however I never realised that it was known as Magic
Numbers. Was someone in Sun smoking something at the time when they
came up with that name I wonder?

I don't even remember the first time I heard the term Magic Number.
I'm sure it didn't have any connection to Java, though.
 
M

Monique Y. Mudama

Hello, All

There are many magic numbers located in our java source code.
Someone pointed out that this is not good coding style. What
dangerous appeared? used Magic Numbers

Thanks

There are a few reasons.

One: at the moment you write the code, you may know very well that 3
represents the number of holes you expect to see in a piece of
notebook paper. But six months from now,

NUM_HOLES_IN_PAPER

is much clearer than

3.

If I've seen one thing in my career, it's that what is "obvious" today
is completely opaque in a few months.

Two: What if you have several classes that have to know how many holes
are in a piece of notebook paper? If you hard-code '3' into several
files, life will be hard when your paper source changes to 2-hole
paper. Also, in every place where '3' is used, you will have to think
about whether '3' represents the number of holes in paper, or whether
it actually represents the number of toner cartridges you had
available. Or whatever.
 
M

Monique Y. Mudama

I had to work with code that had some brilliant lines:

#define PKT_TEN 10
#define PKT_FIFTEEN 15
#define PKT_TWNTYTWO 22
#define PKT_TWENTYTHREE 23

Yes, not only did the previous dev hard-code these numbers, he
actually spelled twenty differently in various packet names.

So then I got to go tracing through the code, trying to figure out
what the heck packet 15 did, anyway.

I forgot to mention the fun part: he and I ended up working on
different projects, but anyway, I got laid off, and he didn't.

My co-workers were livid. (He was infamous for writing awful,
unmaintainable code, so much so that there was a name for his awful
code derived from his last name.)
 
R

Roedy Green

I don't even remember the first time I heard the term Magic Number.
I'm sure it didn't have any connection to Java, though.

I first heard the term in the context of numbers you precalculated.
Today compilers can evaluate the corresponding expressions at compile
time.

There is a magic-number in the Class file format. 0xCAFEBABE. It is
just a signature at the head to identify class files.
 
M

Mike Gaab

Monique Y. Mudama said:
But only if the number or string has the same semantic meaning. If
two numbers appear and happen to be the same value, but one could
change independently of the other, it doesn't make sense to
artificially tie them together.

I know, that should fall under the common sense, but as in other
things, common sense isn't as common as it should be.

I remember discovering the following during a code review:

#define ONE 1
#define TWO 2
#define THREE 3
[...]

...all the way to a hundred or so.

I asked the programmer if he thought that any of these values might
need to change one day (no), or if he could tell me what any of them
meant (only by looking at the code where they were used).

Nobody had ever explained to him the *purpose* of using symbolic
constants, just that it was a bad idea to have the values themselves
directly in the code.

/gordon

Eek.

I had to work with code that had some brilliant lines:

#define PKT_TEN 10
#define PKT_FIFTEEN 15
#define PKT_TWNTYTWO 22
#define PKT_TWENTYTHREE 23

Yes, not only did the previous dev hard-code these numbers, he
actually spelled twenty differently in various packet names.

So then I got to go tracing through the code, trying to figure out
what the heck packet 15 did, anyway.

Hi Monique,

(I love that name. :) )

Just curious, what would have been a better naming scheme?
Sometimes it is really hard to come up with one.

Mike
 
A

Alan Krueger

Roedy said:
There is a magic-number in the Class file format. 0xCAFEBABE. It is
just a signature at the head to identify class files.

A Unix version of Rational's Purify I once used filled uninitialized
memory with 0xDEADBEEF.
 
A

Alan Krueger

Roedy said:
Applause! Did you make that up?

No, it's an observation. How many times have you heard people say
something should be common sense in the context of someone having not
used it?
 
M

Mike Gaab

Thomas Hawtin said:
Overkill? Seems to reduce quantity and improves clarity of the code.

From what I have seen from other posters especially Lasses' post,
I totally disagree. Enums are very OO but, IMO, far from more readable
than a simple named constant. My preference would be to use named
constants but I am not saying there isn't a useful application of Java
enums.

Mike
 
J

josh.s17

I have noticied a trend recently that programmers don't treat Magic
numbers in JSP code in the same way as magic numbers in straight java.
In my opinion magic numbers anywhere are bad and should be avioded.
 
C

Chris Smith

Roedy Green said:
There is a magic-number in the Class file format. 0xCAFEBABE. It is
just a signature at the head to identify class files.

That is, of course, a completely different use of the phrase "magic
number". The two have nothing to do with each other, except that they
are both numbers.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

zero said:
Probably, but I haven't seen any tests (or done any myself) so I'd rather
say that it *might* be an issue than just ignore it and possibly give
someone bad information.

I agree that we should remember programmers generally have poor
intuition about performance. However, the fact remains that all
programmers do have SOME intuition, and there are cases where that
intuition can be reasonably applied.

The overhead for declaring an enumerated type for the seven days of the
week cannot POSSIBLY be significant enough to merit any thought. If it
were, then Sun would have failed miserably and it would be the buzz of
the Java world by now.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

byte[] buff = new byte[8192];

byte[] buff = new byte[SOME_BUFFER_LENGTH];

Monique Y. Mudama said:
Seems like you're dodging the issue here by giving a poor example.
The fact is that you must have chosen 8192 for a reason, and that
reason can be documented with a well-chosen variable name.

Nah, I don't see that that's necessarily the case. When choosing buffer
sizes, it's generally a matter of taking a guess. Usually, the guess is
a power of two, because it works better with MMU/paging architectures
where memory is typically allocated in pages of a power of two in size.
Tuning can be done later if it becomes a performance problem of some
kind. If there's some other kind of ultimate method of calculating
ideal buffer sizes, then most of us haven't yet been informed.

I typically choose buffers of size 32768 unless I have some reason not
to. Obviously, Thomas Hawtin commonly uses 8192. Why? No particular
reason. If it starts mattering in a measurable way, then I'm sure
they'll get tuned, and then a comment will be added explaining the
method used to choose the buffer size and the observed consequences of
making it too large/small.

In any case, even if the buffer size is carefully tuned, I very much
doubt that you could explain the method or logic behind the choice in a
reasonable identifier name.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Thomas Hawtin said:
As a rule of thumb, if a number *or string* appears twice, always give
it a constant (or preferably eliminate subsequent appearances). For
other cases, use common sense.

As Monique implied, there are really two reasons to use a named
constant: (a) it's duplicated, and (b) it can be given a simple name
that's more descriptive than the number itself. You have absorbed case
(b) into "common sense", but IMO it's worth being explicit about.

A lot of programming "rules" like this are based on assuming that (b) --
or its analogue in another code decision -- is true. A lot of the
zealous over-application of these rules comes from people being
unwilling or unaware of the need to make a decision about the truth of
(b).

Ultimately, I'm agreeing with you. There are cases where a number,
properly put into context, is simply more expressive than any possible
logic about where it comes from.

That logic is either clear from the usage, as in:

if (mode.equals("biped")) numLegs = 2;
else numLegs = 4;

(versus)

final int BIPED_LEGS = 2;
final int QUADRUPED_LEGS = 4;

if (mode.equals("biped")) numLegs = BIPED_LEGS;
else numLegs = QUADRUPED_LEGS;


or it can't be expressed in an identifier anyway, as in:

/*
* According to Dr. Seorge in his 1992 paper in "Transactions of
* the American Journal of Rocket Science", the amount of fuel
* should be calculated by this formula:
*/
double amountOfFuel = 14.97264 / (1.493 + numEngines + numFins);

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Roedy Green

The overhead for declaring an enumerated type for the seven days of the
week cannot POSSIBLY be significant enough to merit any thought. If it
were, then Sun would have failed miserably and it would be the buzz of
the Java world by now.

I have done a fair bit of staring at decompiled enum code to figure
out how it works.

The crucial problem with type-safe enum kludges is getting a decently
fast SWITCH. The Java enum implementors went to considerable
shenanigans to implement the switch with a plain old jump table using
a fast tableswitch JVM instruction instead of a lookupswitch.

It looks like this to ensure dense ints even for very large enums.
// use an ordinary int switch, using pre-mapped ordinals to sort the
switch.
switch ( $switchMap[ breed.ordinal() ] )
{
case 1: // DASCHUND
return true;

case 2: // DALMATIAN
case 3: // LABRADOR
default:
return false;
}
 
R

Roedy Green

That's fine, but he wasn't a clever programmer rebelling against
anything.

that is part of the fiction of the essay -- that writing
unmaintainable code is done deliberately, and this is a how to essay.
 
A

Alan Krueger

Mike said:
From what I have seen from other posters especially Lasses' post,
I totally disagree. Enums are very OO but, IMO, far from more readable
than a simple named constant. My preference would be to use named
constants but I am not saying there isn't a useful application of Java
enums.

Let's turn this around. Is it *less* readable that a simple named
constant? It's certainly less type-safe. You can have completely
readable, compilable code that's entirely wrong.
 
R

Roedy Green

IMO, far from more readable
than a simple named constant. My preference would be to use named
constants but I am not saying there isn't a useful application of Java
enums.

But to the client of the enum, the enum constant looks almost
identical to the old C style named constant. It just points to an
object instead of an int for type safety. You use them almost the same
way.

Before you give up on enum, try them out for some simple project. They
are definitely peculiar, but they do work reasonably well in practice.

see http://mindprod.com/jgloss/enum.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top