tags:

views:

434

answers:

14

Hi there,

A developer in a team I'm supervising prefers declaring variables as constants in his tests, e.g. const int someValue = 1; (rather than just int someValue = 1;).

When I saw this I found it a bit odd and questioned what he'd done. His argument is that this is sensible for the purposes of this test - because the value he's assigned never changes.

I've always thought of constants as something that should be declared at a class level. However I do see this developer's point of view.

What's your opinion? And, tests aside, would you declare constants in normal methods? If 'yes', why?

+3  A: 

The idea is that you only leave stuff mutable if there is a specific reason for it—it makes it easier to reason about your code that way.

Hank Gay
+2  A: 

Of course a value that needs to be given a name, but that does not need to change, should be called a constant, since that is what it is.

Sure, sometimes a constant can be part of an interface, and/or need to be used in a broader scope, and then it must be declared in a suitable place. But if it is really local, then I find nothing strange about making it so.

unwind
+8  A: 

If the identifier is only used within the function it is declared, why polute a wider scope with it. If the value assigned to the identifier should not change then marking it as such is useful to the compiler as well as spotting bugs.

AnthonyWJones
+19  A: 

In general, I think it's always a good idea to make your intentions clear this way, for a number of reasons:

  • It's easier to understand what you meant when you wrote it.
  • It's easier for others to reason about your code when they read it.
  • It's easier for the compiler to make inferences about what you want to do.
  • It's easier for the compiler to prevent logical errors.

Making variables constant is a perfectly legitimate way to accomplish all of the above, in the specific case of intending "I don't want this variable to change its value".

John Feminella
+2  A: 

If the value is scoped to the method (i.e. not used externally, but used a few times inside), then it makes good sense. In particular, if working with xml you might have something like an xml namespace that is used (in only one method) several times, but it certainly not something you want to maintain more than once - const is ideal.

In terms of C#, this also has impact for closures:

const int i = 27;
Func<Foo,bool> predicate = foo => foo.Bar == i;

is different to:

int i = 27;
Func<Foo,bool> predicate = foo => foo.Bar == i;

The second must generate a capture class, etc - the first is just a static method (without state), and more efficient (no heap object per usage, no de-reference, etc).

Marc Gravell
Isn't the compiler smart enough to detect this?
erikkallen
+3  A: 

If you are going to use a statically typed language, then why not just go the whole nine yards? Use const to indicate that you don't want the value to ever change after the first assignment. Let the compiler bug you if you goof.

I quite liked the const keyword in C++ method parameters for exactly this reason...

Daren Thomas
+1  A: 

Declaring a variable constant will prevent you from accidentally changing it's value. This can also lead to compiler optimizations.

SmuK
A: 

I've never seen this before but it does make sense. I would let the programmer keep going the way he has already been developing.

Alex
+1  A: 

I tend to declare any value which doesn't change const/final, and encourage others on teams I work with to do the same. Usually in Java, where final means 'assigned once and once only' rather than C's const 'initialised and not changed', you can create methods where the only non constant values are loop iterators.

Pete Kirkham
+1  A: 

Do it everywhere where its possible:
- it make code easy for reading;
- it ask compiller to check your occasionly errors:

void some_class1::doSomething( const some_class2& cs2)
{
// code
cs2 = cs2; // !!! misspelling cs2 instead cs2_
//
}

- it help you with compatibility with const correct code;
- it help with incapsulation;

bb
+8  A: 

From Effective C++ by Scott Meyers (chapter 3):

Use const whenever possible.

The wonderful thing about const is that it allows you to specify a semantic constraint - a particular object should not be modified - and compilers will enforce that constraint. It allows you to communicate to both compilers and other programmers that a value should remain invariant. Whenever that is true, you should be sure to say so, because that way you enlist your compilers' aid in making sure the constraint isn't violated.

Bill the Lizard
A: 

For tests, this is obviously great. As for 'regular' code, you could look at it from both ways. On one end, the scope of anything in code should be as small as possible. On the other end, you could say that a constant is more likely to be used troughout a class and should therefor be declared at the class level at all times, to prevent double constants.

I would say, declare class level constants only and use method constants only when there is a good reason for it. One reason could be that a methods purpose is to provide abstraction on some API call and you require some constant values for this. In this case you don't want class level constants to clutter the rest of a class.

Jonathan van de Veen
+1  A: 

The advantage of declaring it const is that you can't "accidentally" modify it in an obscure way which code inspection might miss. For example by passing it by reference into a function which modifies its parameter.

The arguable disadvantage is that you can't (easily) pass it into code which takes non-const reference that it doesn't actually modify. If you really believe in C++, this is actually an advantage in disguise, because it encourages you to make the rest of your code const-correct. But if you have to make quick changes (e.g. when debugging), or if you've already published the API and can't change it, then it looks to you like a darn good disguise.

If functions are short, then you don't really need "const" to tell you whether or not a local variable is going to be explicitly modified by assignment. You can see all the uses of the variable right there, in front of you. But in real life, where functions sometimes get long; and where people use non-const reference parameters and sometimes even macros; and where you want to read and understand code as quickly as possible; then it can help a bit.

I tend to use it when I remember, and not sweat it if I forget. I get most use out of it when I need to remove const from a variable. That tells me that my original conception of that variable was wrong, and I need to carefully check that no expression using it actually relies on it not changing. Given that C++ has the const keyword, if you're going to write code that relies on a variable not changing, you may as well get the compiler on your side.

It's usually not worth worrying about compiler optimisations. A good compiler (gcc) can tell that if you don't modify a variable, and don't take any references to it, then it can apply appropriate optimisations whether you mark it const or not.

Steve Jessop
+1  A: 

A lot of seasoned C++ developers actually believe that "const" should be the default, and you would have to explicitly declare something to be non-const. Of course, use const whenever it makes sense to do so. If something shouldn't change inside a function, make it const. It doesn't cost anything, and it helps declare intent.

Brian Neal