72

Many of the books that I am reading use keyword const when the value of a variable should not be modified. Apart from specifying to readers of the code that you may cause errors if you modify this variable (you can use comments to do this), why would you need that keyword to be a part of any programming language? It seems to me that if you don't want a variable modified, simply don't.

Could someone clarify this for me?

syb0rg
  • 8,057
  • 9
  • 41
  • 81
FutureSci
  • 1,750
  • 1
  • 19
  • 27

11 Answers11

101

Apart from specifying to readers of the code that you may cause errors if you modify this variable(you can use comments to do this)

Not "may"; will cause errors in your program.

  • A C++ compiler will enforce it with compilation failures and diagnostic messages ("compiler errors"), with no need for comments;
  • A C compiler will enforce it for the most part, though its standard library has holes thanks to legacy, such as strchr, and it has some rather lenient implicit conversion rules that can allow you to drop constness without realising it quite easily. However, just because you got a successful compilation doesn't mean that you don't have errors; unfortunately, it does mean that the errors can be subtle bugs in your program, as well as big, spectacular crashes.

Either way, your program is guaranteed to contain an error inside it.

It seems to me that if you don't want a variable modified, simply don't.

Well that's all well and good, but nobody's perfect. Programmers make mistakes. This allows the compiler — which never makes mistakes (at least, not usually) — to point them out to you.

It's of particular use when you're using some data variable many, many lines of code away from where it was created. The further away it is, the easier it is to modify it without realising that you were not supposed to. For large, complex code bases it is simply a must.

You get a new measure of provability, correctness and stability in your code base, as well as a huge chunk off possible causes of really subtle and nasty bugs. There are also vast optimisation opportunities for your compiler (in some cases) when it knows that some value won't change after compilation.

We could list the advantages all day but, really, you won't fully grok it until you've worked on such a codebase.

In fact, in a perfect world, all variables would be const by default, and you would need to declare them with the keyword mutable to be able to change them. C++ is backwards.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 17
    I want to live in that perfect world! – Captain Obvlious Aug 10 '13 at 00:51
  • 1
    Scala is this perfect world: immutability is encouraged, collection classes are immutable by default and you need a specific keyword `var` to declare non-mutable variables. – ouah Aug 10 '13 at 00:54
  • 21
    @ouah: Scala isn't really that perfect world. It encourages immutability. Haskell (for one example) enforces it. – Jerry Coffin Aug 10 '13 at 00:55
  • 1
    @Eric: In C++, `strchr` returns `const char*` when the first argument is `const char*`. You're right that C99 always returns `char*` — probably a throwback for compatibility to C89 & C90. Yes, there are gaps in standard library `const`-safety here and there, where legacy has taken its toll, but these are not language holes _per se_ and certainly not a reason to avoid using `const`. – Lightness Races in Orbit Aug 10 '13 at 01:54
  • @Eric: C is indeed rather lenient with its implicit conversions. – Lightness Races in Orbit Aug 10 '13 at 01:57
  • @Eric: Is it better now? Note I make a distinction between "compile-time diagnostic messages" and "errors" (which may not mean a compiler error, but any fault in your program). – Lightness Races in Orbit Aug 10 '13 at 01:59
  • But will the Martians _grok_ it? ;-) – chux - Reinstate Monica Aug 10 '13 at 04:55
  • 22
    "in a perfect world, all variables would be const by default": wouldn't they they be called invariables? – JulianSymes Aug 10 '13 at 12:26
  • 2
    +1. After some experience with Haskell and concurrent programming, I've come to the same conclusion *"all variables would be const by default"*. In fact, it is philosophically *unsound* if a variable is *mutable* **by default**. It has the same philosophical problem if members of a class are public *by default*. – Nawaz Aug 10 '13 at 12:50
  • @Nawaz: I'm not entirely sure what philosophy has to do with it :P – Lightness Races in Orbit Aug 10 '13 at 16:48
  • 1
    It makes linguistic sense for a variable to vary, although if you learned mathematics before programming, you might have [other ideas](http://en.wikipedia.org/wiki/Variable_(mathematics)#What_it_means_for_a_variable_to_vary). – Hugh Allen Aug 10 '13 at 17:54
  • @Hugh: The idea here is that pieces of data should not be variables by default at declaration. – Lightness Races in Orbit Aug 11 '13 at 12:09
42

At least in C++, const has some uses beyond just documenting your intent to other programmers.

const can also tell the compiler some things. For example, a function that takes a reference, like: void f(T &t); can't accept a temporary object as its parameter. To get it to do so, you need to const qualify the reference, like: void f(T const &t).

Likewise, to invoke a member function on a const object, the member function must be const qualified like: void T::foo() const {}.

In an embedded system, const can mean more still, possibly telling the compiler about where to locate the object in question (putting it in ROM vs. RAM). const by itself isn't necessarily enough tell it "put this object in ROM", but it's still often a prerequisite.

Likewise (under C++11) const tells the compiler about thread safety.

Now, it's undoubtedly true that you could define some other language that (in other ways) bore some resemblance to C or C++ that didn't use const in these ways. The result would be a rather different language from either one though. Without knowing your intent, it's impossible to say how it would turn out, but it might end up closer to Java or C# (for a couple of examples) both of which are somewhat similar to C and C++ in some ways, but not this particular one (i.e., don't use const like C and C++ do).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Java doesn't use `const` at all, if I recall. (I think it's a reserved word, but not usable for anything.) Its `final` keyword is similar but not quite the same. C# has `const`, but it's not the same. (I think it's mostly just equivalent to `#define`s.) – Darrel Hoffman Aug 11 '13 at 02:59
38

Besides the usual programming considerations already discussed in other answers, one thing that concerns me is the attitude:

It seems to me that if you don't want a variable modified, simply don't.

A general rule of thumb is that 20% of the cost of writing code is spent in the development phase. The other 80% is spent over the lifetime of the code upgrading it, maintaining it, etc. This means that many other people will work on your code other than yourself.

Time spent during development that avoids problems years later is a good investment. This effort includes: writing comments; defining constants that are constants; and writing explicit code that does not rely on obscure language constructs.

Also, @worlboss, I hear a fair amount of intolerance. As some others have commented, carbon units make mistakes and anything a silicon unit can do to help avoid mistakes is appreciated.

syb0rg
  • 8,057
  • 9
  • 41
  • 81
JackCColeman
  • 3,777
  • 1
  • 15
  • 21
  • 9
    +1 for mentioning the 80% in maintenance that most people forget about. – Thomas Matthews Aug 10 '13 at 01:43
  • That 20% seems high. It might be 20% ***if*** all the right things were done in the beginning. Unfortunately, that doesn't seems to always happen. – user606723 Aug 11 '13 at 05:54
  • @user606723, it's a rule of thumb. If the development phase costs more than planned then 20% does increase as fraction of the total lifetime cost of the software. – JackCColeman Aug 11 '13 at 06:28
  • 1
    @JackCColeman, I was saying that 20% seems high. I think it's close to like 10-15% – user606723 Aug 11 '13 at 13:05
21

It tells the compiler that the variable should not be modified so if someone writes code that modifies it, the compiler flags it as an error.

edtheprogrammerguy
  • 5,957
  • 6
  • 28
  • 47
  • 2
    I'll bet the performance-related benefits were also very important at the time this came around. – chris Aug 10 '13 at 00:52
17

Two reasons:

  1. compiler enforced documentation
  2. compiler optimizations

Here is a good explanation from Ian Lance Taylor (who worked on gcc and gold linker):

The first meaning of const has a real effect on the program. A variable declared const may be compiled differently from a variable which is not declared const.

The second meaning of const, on the other hand, is, in effect, compiler-enforced documentation. The compiler will issue an error if an attempt is made to change a value using a const qualified pointer, but declaring such a pointer will not change the generated code.

Community
  • 1
  • 1
ouah
  • 142,963
  • 15
  • 272
  • 331
  • @LightnessRacesinOrbit maybe because for API you will certainly use `const` only with pointer parameters – ouah Aug 10 '13 at 01:09
  • I'm sorry? I don't follow. – Lightness Races in Orbit Aug 10 '13 at 01:10
  • @LightnessRacesinOrbit in API good practices `const` is usually discouraged for non-pointer function parameters because it reveals the internal of function definitions – ouah Aug 10 '13 at 01:17
  • @ouah I don't get the reference. – Yakk - Adam Nevraumont Aug 10 '13 at 01:24
  • 1
    @ouah: What? No it doesn't. `const` is in fact _ignored_ (by the language) on arguments (whether they're pointers or not is irrelevant; you're talking about applying `const` to the underlying pointee type rather than the function argument type itself) in declarations, because it's meaningless. It's useful only for localised `const`ness in the function _definition_. So how can it have any bearing on the API? – Lightness Races in Orbit Aug 10 '13 at 01:36
  • @LightnessRacesinOrbit for example: `int foo(const int a) { return ++a; }` here `const` is not ignored by C: this example example is not valid C. Now take this valid example: `int bar(const int a) { return a + 1; }` although it is valid the `const` qualifier is discouraged by API good practices because it reveals the internal of the external function `bar`. – ouah Aug 10 '13 at 01:44
  • 3
    `[C++11: 8.3.5/3]:` _[..]_ After producing the list of parameter types, **any top-level _cv-qualifiers_ modifying a parameter type are deleted when forming the function type**. _[..]_ – Lightness Races in Orbit Aug 10 '13 at 01:49
  • 1
    `[C99: 6.7.5.3/15]:` _[..]_ (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and **each parameter declared with qualified type is taken as having the unqualified version of its declared type**.) _[..]_ – Lightness Races in Orbit Aug 10 '13 at 01:51
  • 1
    ^ the API (function _declarations_) doesn't even get to _see_ the `const`s. Re-application in the function _definitions_ is not relevant. – Lightness Races in Orbit Aug 10 '13 at 01:51
  • @LightnessRacesinOrbit fair enough, I was actually not aware of this rule, thanks for pointing it out. – ouah Aug 10 '13 at 01:52
6

Here is a simple C example:

void PrintList(const struct List *l);
void SortList(struct List *l);
int  CmpList(const struct List *a, const struct List *b);
void AppendList(struct List *l, struct List *m);
void PushList(struct List *l, struct ListNode *n);
void PopList(struct List *l, struct ListNode *n);

Here we have a small set of functions that work with some kind of list of nodes. First, without even knowing the names of the functions we can see immediately which functions change our list in some way, and which ones don't. The const functions, like in the standard libraries, are ones that do not change your data, and won't allow you to change your data with them. The C compiler tries to keep the const-ness of the pointers enforced to the data you are passing to the functions. So in this case I can be reasonably sure that comparing two lists isn't the function that is mangling them when I do my runtime debugging, as I have protected myself against accidental modifications to my data. ;)

CyberSkull
  • 796
  • 1
  • 7
  • 16
5

Your compiler can make big optimizations, knowing that a variable won't be changed: instead of storing it in memory, it's directly written into the executable opcode.

example: you have a and b, you want to add them, you make a + b. If you declare a to be const and of value 3, the program will make 3 + b instead, which will save memory and cycles becayse it won't need to retrieve the a value.

The problem is that your compiler cannot know in advance if variables are constant or not, of course it could analyze the whole code and check whether you modified such variables, but it's not 100% sure, since future code can also modify it.

jokoon
  • 6,207
  • 11
  • 48
  • 85
4

Keyword const is very useful for teams and long term projects. I'll give you few examples, those should explain value of const keyword.

Lets say now I'm creating lib that will be used for further projects. So it means that code written today needs to be trusted after a few years, in such a period of time probable I will forget which variable shouldn't be modified (colleagues even do not know what can be modified and what cannot). So this short example explains why to use const.

Talking about comments, when the deadline is coming and there is plenty of stuff which still not working comments on every function would be just a waste of time. However in some cases comments is a must, because of the first problem (deadline) comments may be not read, because most them are useless but important comments will be skipped too. So it is better to use const keyword which gives compilation error and points you into the problem then writing and reading lot of comments.

ST3
  • 8,826
  • 3
  • 68
  • 92
3

This is a hard question because IMO it is based on beliefs. One of those beliefs is that you can protect your code against some kind of changes just adding more code. Of course, that extra code is used by the compiler to check everything is alright.

I think that is not always right, you cannot protect your code against yourself or your development team just adding keywords, in fact there are lots of languages which don´t have any const, public, private, protected, internal, int, float, double keywords and that doesn´t mean they are not good languages.

The same happens with some code patterns, why do people wasted so much time discussing about Singletons!? If you want to have only one instance, the only thing you have to do is to create just one instance, that´s all. The same mindset is everywhere around, take a look at the defensive programming articles published 10 years ago, once more the idea of protecting code with code.

In some point you have to decide where you want to set the responsibilities, on the developers' hands or on the compilers' ones. However, neither the compiler nor any other tool can save the code against the developers and for that reason lots of keywords are worthless or just a way to communicate something to other developers.

lontivero
  • 5,235
  • 5
  • 25
  • 42
1

Constant variables just allow you to write more readable code.

The most use for const in almost all languages is to allow us to use names to refer to constants values, so you can tell to others, using fluent language, what this name refers to without needing to spread comments in your code and saving time and effort from the readers to know the parameters type and particularities of the parameters. Of course, you benefit also if your constant value is reused across your code. Well, a code like this can be more readable:

processPages(LETTER_PAPER_WIDTH, LETTER_PAPER_HEIGHT);

...than this:

processPages(215.9, 279.4); // 8.5 x 11 Inches in millimeters for Letter Papers

In the above example, you need to understand what each parameter is, its unit and the type to interpret the values, and you need yet to validate it against the comment, because a redundant comment like this (those comments that replay what is coded) isn't a reliable and so useful comment (is a bad comment acording to Robert Martin in Clean Code: http://goo.gl/5EyY).

Luciano
  • 2,695
  • 6
  • 38
  • 53
-2

Consider the scenario where you are using the same constants many times in your entire project and you are hard coding it at all places. Now suddenly you are required to change the value of constant to another value, so it will be hectic to do changes at all the locations.

So I think to make your code more maintainable definitely be one of the reason.

Mohan Mahajan
  • 1,501
  • 3
  • 12
  • 19
  • 3
    -1. While your answer is true in itself, it has little to do with the question asked. The question was about why to use the const modifier, the answer is about why to define in a single place. – Emilio M Bumachar Aug 10 '13 at 18:03
  • I admit my mistake of taking the question other way around. Sorry my mistake! – Mohan Mahajan Aug 12 '13 at 17:07