Why would you use the keyword const if you already know variable should be constant?
Asked Answered
R

11

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?

Rodd answered 10/8, 2013 at 0:37 Comment(13)
Why use protected or private? Or abstract? Or final?Pren
const is a reserved word in Java, but it has no purpose.Urien
Why use functors to access private variables?Elaterid
Remember that a lot of keywords and concepts are there to help programmers, not programs. const is a little bit of both.Fig
Omitting const would work very well for programmers who never make mistakes.Merchantable
Stroustrup put it best: compilers don't read comments. Maybe you think you are better at following rules than a compiler.Arciniega
When doing embedded systems programming, having a const specifier would offer the compiler and linker the option of mapping the value's address to an EPROM section of memory rather than in RAM. I worked on a system many years ago that had this behavior for pre-assigned static variables (before the const keyword was introduced).Brouhaha
You might want to have a look at Python constants ;)Generatrix
look up defensive programmingCyrenaic
Similar to the embedded systems example, the linker can also put const globals in a read-only section which can be shared across multiple processes.Mow
If I designed my own language, const (or read-only) would be the default, and you'd need to add a keyword, maybe var, if you wanted to be able to modify an object after it's declared and initialized.Merchantable
So, did you get your answer?Stearic
@worlboss: Then would you mark it as accepted please? You know how SO works.Stearic
S
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.

Stearic answered 10/8, 2013 at 0:41 Comment(12)
I want to live in that perfect world!Lachrymose
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.Celtuce
@ouah: Scala isn't really that perfect world. It encourages immutability. Haskell (for one example) enforces it.Marchioness
@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.Stearic
@Eric: C is indeed rather lenient with its implicit conversions.Stearic
@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).Stearic
But will the Martians grok it? ;-)Goldenseal
"in a perfect world, all variables would be const by default": wouldn't they they be called invariables?Tedder
+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.Oxycephaly
@Nawaz: I'm not entirely sure what philosophy has to do with it :PStearic
It makes linguistic sense for a variable to vary, although if you learned mathematics before programming, you might have other ideas.Grandma
@Hugh: The idea here is that pieces of data should not be variables by default at declaration.Stearic
M
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).

Marchioness answered 10/8, 2013 at 0:52 Comment(1)
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 #defines.)Extrusion
D
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.

Dahl answered 10/8, 2013 at 1:29 Comment(4)
+1 for mentioning the 80% in maintenance that most people forget about.Groggy
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.Clementinaclementine
@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.Dahl
@JackCColeman, I was saying that 20% seems high. I think it's close to like 10-15%Clementinaclementine
H
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.

Hyonhyoscine answered 10/8, 2013 at 0:39 Comment(1)
I'll bet the performance-related benefits were also very important at the time this came around.Confiture
C
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.

Celtuce answered 10/8, 2013 at 0:59 Comment(10)
@LightnessRacesinOrbit maybe because for API you will certainly use const only with pointer parametersCeltuce
I'm sorry? I don't follow.Stearic
@LightnessRacesinOrbit in API good practices const is usually discouraged for non-pointer function parameters because it reveals the internal of function definitionsCeltuce
@Celtuce I don't get the reference.Perforce
@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 constness in the function definition. So how can it have any bearing on the API?Stearic
@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.Celtuce
[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. [..]Stearic
[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.) [..]Stearic
^ the API (function declarations) doesn't even get to see the consts. Re-application in the function definitions is not relevant.Stearic
@LightnessRacesinOrbit fair enough, I was actually not aware of this rule, thanks for pointing it out.Celtuce
G
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. ;)

Gambit answered 10/8, 2013 at 12:25 Comment(0)
P
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.

Parapodium answered 10/8, 2013 at 10:5 Comment(0)
A
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.

Argentum answered 12/8, 2013 at 12:30 Comment(0)
O
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.

Orison answered 14/8, 2013 at 1:32 Comment(0)
V
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).

Vitiated answered 13/8, 2013 at 21:8 Comment(0)
F
-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.

Fission answered 10/8, 2013 at 5:51 Comment(2)
-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.Hurlbut
I admit my mistake of taking the question other way around. Sorry my mistake!Fission

© 2022 - 2024 — McMap. All rights reserved.