tags:

views:

1076

answers:

12

In the following C++ functions:

void MyFunction(int age, House &purchased_house)
{
    ...
}


void MyFunction(const int age, House &purchased_house)
{
    ...
}

Which is better?

In both, 'age' is passed by value. I am wondering if the 'const' keyword is necessary: It seems redundant to me, but also helpful (as an extra indication the variable will not be changing).

Does anyone have any opinion as to which (if any) of the above are better?

+5  A: 

See Meyers and 'Effective C++' on this, and do use const liberally, especially with pass-by-reference semantics.

In this case of atomic variables, efficiency does not matter but code clarity still benefits.

Dirk Eddelbuettel
I would disagree in the case of a pass by value primitive type. I would do a double take if I saw that in the code, since the callee can't change the value (from the caller's point of view). I would wonder if there is some typo, of if the person writing the code just doesn't understand pass by value.
Dolphin
@Dolphin: Then you should read litb's (as ever) excellent treatment on the subject, learn, and stop to wonder. If whether code feels "natural" or "used to" was a criterion for correctness, nobody would have started to use the STL for all these funny iterators that felt so unnatural at a first glance.
sbi
If they had avoided that, maybe we'd have decent support for ranges in C++ by now ;-p
Steve Jessop
@onebyone: I'm with you on that, actually. `:)` I'm not sure about the impact of the removal of concepts, but there is IMO decent range support going to come with C++1x.
sbi
@sbi, hmm, i'm with dolphin, he seems to agree with what i say in my answer.
Johannes Schaub - litb
+6  A: 

You not only indicate that it will not change, it will prevent your code from thinking it can and it will be caught at compilation time.

Locksfree
+29  A: 

First, it's just an implementation detail, and if you put const there, don't put it in the declaration set (header). Only put it in the implementation file:

// header
void MyFunction(int age, House &purchased_house);

// .cpp file
void MyFunction(const int age, House &purchased_house);
{
    ...
}

Whether or not a parameter is const in a definition is purely an implementation detail, and should not be part of the interface.

I've not seen this sort of thing often, and i also don't do this. Having the parameter const would confuse me more often than help, because i would immediately pattern-match-fail it to "const int &age" :) The matter of course is entirely different from having const at another level:

// const is a *good* thing here, and should not be removed,
// and it is part of the interface
void MyFunction(const string &name, House &purchased_house);
{
    ...
}

In this case, the const will affect whether the function can change the caller's argument. Const in this meaning should be used as often as possible, because it can help ensuring program correctness and improve self-documenting the code.

Johannes Schaub - litb
Brian
@Brian, i have not said that. The question is about when you pass the argument by value. In this case, it's an implementation detail when you put const at the top-level and make the parameter itself const thereby.
Johannes Schaub - litb
Lets not forget that you can overload a member function only by changing it's constness (can you even say this?)
Gab Royer
@San Jacinto - The caller already knows that it's not going to modified on return from the function, because it's not returned from the function: it's pass by value, so you'e passing in a copy and getting nothing out. As for whether the callee modifies his local copy, that's an implementation detail (in the CPP file not in the header).
ChrisW
San, the point is that top-level consts on parameters are ignored in function declarations, i.e. `int foo(int)` and `int foo(const int)` are equivalent. The top-level const is not part of the contract, it only affects whether the parameter can be modified in the body of the function.
avakar
@gab: But you cannot overload it on the constness of a parameter past by value. Hence litb's excellent suggestion.
sbi
I understand the technical differences. What I am saying is that as a programmer using someone else's code, I want the assurance that my foo is going to be the same coming back out, or I want to know that it COULD be changed inside the other guy's code. Additionally, I don't want to look. I guess, however, that there is a lot to be said for the fact that later on down the line the other guy can change it back without letting me know, and now I'm equally screwed.
San Jacinto
@San: I think you miss the point: Whether there's an additional `const` in the cpp file or not doesn't change anything. (If it did, the compiler would complain.) And the risk that someone changes their function to take a non-const reference instead of a copy is there anyway, _does_ make a difference to the caller, and the compiler very likely won't warn you about that change at all.
sbi
Thank you for your patient explanations. I am thoroughly confused now. my compiler (GCC on cygwin) complains in both cases and won't compile unless the .h prototype exactly mirrors the cpp. if const is in one, it must be present in both.
San Jacinto
Didn't mean to make that last comment sound sarcastic.
San Jacinto
avakar
That's exactly what I was doing. Thanks. I'm back now. Pass by value wouldn't make a difference if it was const or not. I see what sbi and others are saying now.
San Jacinto
@San: I indeed tried to be patient, so it didn't even occur to me to take your expression of gratitude as sarcastic. `:)` I'm glad avakar was able to guess the problem and you found out what this is about.
sbi
Thanks folks for all the help explaining stuffs. Greatly appreciated.
Johannes Schaub - litb
-1 Even if it compiles, writing the const in the .cpp and not in the .h could lead to confusion. I believe you should put a const in the .h and .cpp simply to inform with the signature of the method/function of the intentions of what will be done in the .cpp. In my experience, doing what you are suggesting is like searching for trouble since it would add unnecessary problems.
Partial
"simply to inform with the signature of the method/function of the intentions of what will be done in the .cpp" -> no that's exactly *not* what an interface is about. An interface is about *not* knowing what an implementation does and how it looks. I do *not* suggest writing const in the cpp and not in the header: What i recommend is writing const nowhere: "I've not seen this sort of thing often, and i also don't do this. Having the parameter const would confuse me more often than help"
Johannes Schaub - litb
Thanks for informing me though that you don't agree with me. But i don't see what problems it would *add*. It seems to me that it rather *reduces* problems, since it removes one more piece of code that's got no information attached. What would it tell you as a reader of the header file? If it's the implementation-detail, why don't you say in the header "in the function, there are two for-loops and one if-clause" likewise, if you want to expose the implementation?
Johannes Schaub - litb
@litb: I really hope you do use constants. The role of a constant is to forbid the modification of a variable. Now, with this being said, if the signature of a certain function/method has a constant passed by value it simply means that the function/method guarantees it will not allow anything to modify it. Otherwise, any information could be spread to other functions/methods and be modified along the way. It is basically a safeguard. In other words, the function/method is committed to never change the variable passed by value.
Partial
@litb: Once the information is passed to the function/method it is responsible of the copied information. If you are ready to take the risk that it will be changed along the way or be copied everywhere I really do not understand your point of view.
Partial
@litb: Can I propose the following maxim to you? If an object/variable can be qualified has being constant, it should be. At worst, it will not cost anything. At best, you will be documenting the role of the object/variable in your code and it will allow the compiler the opportunity to optimize your code even more.
Partial
@Partial: I am pretty sure you don't understand how "pass by value" works. The function gets a copy of the data. Even if it is modified inside the function, the change is not to the original data. For example, the function `void f(int k) {k += 10;}` does absolutely nothing.
rlbond
@Partial, well you seem to say that whether the parameter is const or not affects the caller in a way. But it doesn't. You cannot have changes passed "along the way": You pass the argument by value, so you cannot change it, whatever you do. See the explanations of @ChrisW and others above. I will make variables const if they aren't changed. But i won't do so for parameters - it confuses me and it confuses other people (see other answers of this question). Yet, it's not a particularly bad style - but look around and tell how many people do it and understand it.
Johannes Schaub - litb
@rlbond: Here is what I said in one of my comments: "the function/method it is responsible of the copied information". Now for sure what you wrote does absolutly nothing! What about something like this .h: void Write(int k); and for some reason in the .cpp be void Write(int k){cout << k+10;} You probably were expecting it to write the Original number but instead it does not! If there would of been a const in front of the int you would have been sure that Write is really writing what you want. Of course this is really a basic example. If you do not understand I'll create an exhaustive example.
Partial
@Partial, that's a strange definition of "const": if you make a by-value parameter const, you say that the parameter doesn't change. But you don't determine any particular behavior: You can just copy the parameter, and operate on the copy (this is, in fact, what you do with "k + 10") - behavior would be the same as when you would operate on the parameter directly. So as a consequence, a "const" value-parameter is not part of the interface, and has no place in the non-defining declaration set of the header.
Johannes Schaub - litb
@litb: Why would it confuse you? The variable passed by value into the function/method is copied to a constant inside the function/method. It is a straightforward concept. Why would you do that? To protect the copied data. Why would you protect the copied data? So that it is not modified for an operation since it should remain intact. Why should it remain intact? Because the data is perhaps sensitive! Because the data is perhaps encrypted! Because the data should perhaps be unique! And so on... Again you use a constant when you need it. Refer to my previous comment for a maxim!
Partial
In any case, i'm not sure i understand your example. I would welcome a more exhaustive example, if you don't mind.
Johannes Schaub - litb
@Partial, with regard to the maxim - i program not for maxims, but for productivity. Or at least i try to do so. A const in a value parameter goes against my intuition, and i easily read it as a typo for a const reference parameter (`const` parameters mean to me: "promise to the caller about not changing the argument" - but in that case, const would mean something totally different). So whatever maxime is there, i only follow it if it increases productivity for me.
Johannes Schaub - litb
@litb: Do you use constants and where do you work to rarely see constants in parameters? Just for the sake of it have you ever used the keyword volatile?
Partial
@litb: Anyway, you can have a look at my answer for the example and explanation... Unless you are alone for a project (which is rare enough) you must think ahead for anyone else that will ever have to look or use your code and that can boost productivity thinking ahead of what others could possibly do with your code! Even if you are alone, make it a standard to write safe code.
Partial
@Partial, apart of some theoretical discussions, i'm not seeing "const" value parameters in practice. Looking at boost, at llvm and clang, noone does it. And neither do i, for the reason i stated above. So, to say it again so it's clear: *I'm not saying that the "const" is pointless*, but i say i won't write it. It surely adds safety. You may write it if it helps you.
Johannes Schaub - litb
@Partial: That's a pretty poor argument. Your function would be identical with the `const` keyword.
rlbond
Partial
@litb: So if boost, at llvm and clang would jump down a bridge would you blindly follow and not question anything?
Partial
@litb: Not only does 'const' helps me it makes my code more optimized, it makes it safe for myself and for who ever will have to use it. If you think this is pointless, well it is just too bad for you!
Partial
@litb: Learn to use what you have in your toolbox! 'const' is one of those keywords that are useful. Perhaps you always write error free code, but human error is part of everyone else. You should never take into consideration that others will write good code. Use const and force it upon them.
Partial
@litb: Have a look at this article: http://www.linuxjournal.com/article/7629
Partial
+1  A: 

One benefit of using const is that you cannot accidentally change the value of age in the middle of MyFunction (in the event you forgot it was not pass by reference). One "disadvantage" is that you can't recycle age with code like foo.process(++age);.

Brian
`foo.process(++age)` should be fine since the `const` applies to what `process` can do to the argument - `int age` is mutable... it is _converted_ to `const int` when it is accessed within the function.
D.Shawley
@D.Shawley: I said `foo.process(++age);`, not `MyFunction(++age, bar);`
Brian
+4  A: 

You're correct, the only purpose of "const int age" is that age can not be changed. This can be however very confusing for most of programmers. So if these approach is not used widely in your code, I'd advice to omit const.

dimba
"the only purpose of "const int age" is that age can not be changed" You're saying this as if it was some small thing. IMO the ability to have the compiler check const-correctness is one of C++' greatest strengths.
sbi
I'm all for writing understandable code, but not in exchange for losing out on a compile time check. That said, if this approach is "not used widely in your code", I'd say that your team needs some education and/or better code reviews so that it *becomes* widely used.
JeffH
It almost seems that pass by value should be const by default, doesn't it? And yet this is not a construct that you see in real code very often - in fact I don't think I've ever seen it.
Mark Ransom
I think a big reason you don't see it much, is that people don't like to put the const in the declaration (it's meaningless and verbose), and they like the signature in the definition to be byte-for-byte identical to the declaration (for ease of seeing that they're the same, and for the IDE-challenged also ease of searching).
Steve Jessop
Johannes Schaub - litb
@litb: This is where you are wrong. It is not confusing code. It is safe code. Perhaps you are not used to making your code safe but the extra effort at best makes the compiler optimize your code and at worst nothing less than a safeguard!
Partial
@Partial - nowadays constness can indeed prevent optimization. In addition, an effort to make all const correctness in a big project is really big effort, and if you insist on the really corner constness like in the question it becomes mission impossible ;) As for gain vs effort, this looks not worth.
dimba
@idimba: On the contrary, it actually optimize the code since in the assembler you will have only one variable that will stay the same as opposed to having many variables. On a big project, it will be even more worth while if you use the keyword 'const'. At the same time, with 'const' you get a free check when the code is being compiled to see verify that the constant remains the same. What prevents the compiler from optimizing the code is the keyword 'volatile' which is really useful when doing a multithreaded application!
Partial
+13  A: 

I recommend Herb Sutter. Exceptional C++. There is a chapter "Const-Correctness".

"In fact, to the compiler, the function signature is the same whether you include this const in front of a value parameter or not."

"Avoid const pass-by-value parameters in function declarations. Still make the parameter const in the same function's definition if it won't be modified."

Vanuan
+6  A: 

This, IMHO, is overusing. When you say 'const int age,...' what you actually say is "you can't change even the local copy inside your function". What you do is actually make the programmer code less readable by forcing him to use another local copy when he wants to change age/pass it by non-const reference.

Any programmer should be familiar with the difference between pass by reference and pass by value just as any programmer should understand 'const'.

Oren S
Forcing the programmer to use another local variable name instead of reusing the formal input parameter is a good thing. Reusing the parameter for a new purpose by assigning a new value to it makes the code less readable by giving that name multiple purposes. Some languages don't allow this, example C#.
Brian Ensink
-1. Using const actually helps debugging here. By forcing the programmer to use a LOCAL variable, it helps her (and her readers) to actually understand that the changes are not going to be propagated outside of the method / function.
Matthieu M.
It all boils down to the question "what does the READERs' level in programming and what are they used to?" For a beginner, exceptions, reference semantics and even implicit cast may seem unclear and unreadable. When I write code I try to be clear. I don't, however, aim to be understood by every beginner. It is more important for me to avoid the pattern matching (mentioned by litb and idimba in their answers) the experienced programmer may wrongfully do (much like I will probably do). and I expect the reader to understand pass by copy.
Oren S
Whoa, this answer does not deserve such a low score. Up-voting to counteract.
avakar
To be honest, i don't understand how this is at this low point currently either. He's made a good point that it's just saying something about local things having no effect to the caller. His point of view on the force-creation-of-new-local may be a bit offtopic (btw, http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ *encourages* you to modify the parameter directly), but i don't think it deserves a -5. As others already pointed out, whether const or not, it won't propagate changes to arguments that were passed by value, so the "-1" comment above isn't quite correct either.
Johannes Schaub - litb
Anyway, I'm going to upvote you too to since i basically share your point of view.
Johannes Schaub - litb
@litb: the encouragment is made for speed optimization, which is not the topic of the discussion. For the 'propagation' problem: by creating a local variable you realise that the change won't be propagated. Anyway I admit to being a nitpick there.
Matthieu M.
@Matthieu, i linked to the encourage to show that changing a parameter isn't all that evil. I think his statement sounded a bit offtopic to me because i thought "if you need another local to be able to change it, you wouldn't make the parameter const in the first place" (which is also a point of the encouragement). Now i see some say that C# forbid changing params so i see it certainly isn't offtopic. The caller gives values to the callee, and the callee may then change its copy of those values. It's common for generic algorithms to operate on their iterator parameters directly, for example.
Johannes Schaub - litb
-1: All depends on the purpose of the function/method. None of them is better. If the age must not be modified it should not be allowed to be changed. Otherwise, it could be passed to pretty much anything and be modified somewhere when it should not. Just imagine a function/method that takes a credit card number has a parameter... Do you want it to be copied or changed?
Partial
@partial, none of the prototypes shown in the question will change the actual parameter (the parameter passed to the function). both `age` arguments are passed by value. Even if you pass a credit card number, as long as you pass it by value, it will not change.
Oren S
@Oren S: I know that the original value will not change. The simple fact that the copied value can be copied again and modified is the problem. A constant is a safeguard and it informs any programmer of your intentions towards the what is passed inside the function/method. It is in a way a contract that the function/method gives to anyone using it that it will not change a certain variable inside itself.
Partial
@Oren S: The problem is that sometimes certain programmers are too lazy and write something unsafe rather than giving an extra effort to make it safe. As a C++ programmer you have a responsibility in putting that extra effort to limit human error that could unintentionally modify something somewhere that should have never happen. Not only is it a precaution of putting a const, if you do certain things you should normally not be able of doing with it the code will simply not compile.
Partial
Wow, the number of downvotes on this answer is staggering. To those who downvoted: there is no advantage to taking an argument by const value, and actually, taking a parameter by value can stop a spurious copy over taking a parameter by const reference and later copying it, if the argument is a temporary. Matthieu M and Partial's comments seem amateurish. Those of us who are experienced would notice if a parameter is by copy or by reference, and I for one am not writing worse code just so newbies can read it.
rlbond
@Partial, no it's not a "contract" in any way. If it was, then how is it not a contract to say "in my function, there are two for-loops, and one while loop. The function also has a non-const variable somewhere, which i promise could be changed"? (yes, i exaggerate, but it's precisely the same point: This is entirely private to the function in question, and doesn't concern the caller in any way).
Johannes Schaub - litb
I call bull*** on putting const in there as a rule. The function may need to modify it internally, and its pointless to make a copy just to follow the most overused pejorative term in computer science "const correct". If the function doesn't modifiy it, then make it const.
Justicle
Wait a second, so this gets downvoted because those who read the answer don't understand the language, and the different between pass-by-value and pass-by-reference? Good grief... +1 from me
jalf
Partial
If it would be a const object passed by value, I would agree that it is foolish to do so because it would be better to pass a const reference on an object instead. In our case we are talking about an integer!
Partial
@rlbond: "Those of us who are experienced" Who are you to judge that? The reputation one has on a website is not equivalent nor representative to one's experience! Your argumentation is flawed. Also, have a look the contents of this link: http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
Partial
@Partial, funny that you are getting upset by this. It was *you* that told me i'm perhaps not used to writing safe code. In any case, i've not seen rlbond making any claims that high reputation means anything. You are reading something into his comment that he never said there.
Johannes Schaub - litb
@litb: "Matthieu M and Partial's comments seem amateurish. Those of us who are experienced would notice if a parameter is by copy or by reference, and I for one am not writing worse code just so newbies can read it." Do you understand what he wrote? By saying that Matthieu M comment and my comments seem amateurish and then saying "those of us who are experienced" and "writing worse code just so newbies can read it" implies that he is separating us from people who are experienced.
Partial
@litb: Yes, it is true that he did not claim anything about reputation. It was only frustration from my part because so far a majority of people with high reputation on this site has been saying that using a 'const' in the situation of the question is useless. Sorry about that, but please have a look at my answer and feel free to comment.
Partial
+1  A: 

Having a primitive type that is passed by value const is pretty much worthless. Passing a const to a function is generally useful as a contract with the caller that the funciton will not change the value. In this case, because the int is passed by value, the function can't make any changes that will be visible outside the function.

On the other hand, rreferences and non trivial object types should always use const if there is not going to be any changes made to the object. In theory this might allow for some optimization, but the big win is the contract I mentioned above. The downside is of course, that it can make your interface much larger, and const it a tough thing to retrofit into an existing system (or with a 3rd party API not using const everywhere).

Dolphin
+1  A: 

Well, as other have already said, from the point of view of C++ language, the above 'const' has no effect on function signature, i.e. the function type remains the same regardless of whether the 'const' is there or not. The only effect it has at the level of abstract C++ language is that you can't modify this parameter inside the function body.

However, at the lower level, the 'const' modifier applied to the parameter value can have some optimization benefits, given a sufficiently clever compiler. Consider two functions with the same parameter set (for simplicity)

int foo(const int a, const double b, const long c) {
   /* whatever */
}

void bar(const int a, const double b, const long c) {
   /* whatever */
}

Let's say somewhere in the code they are called as follows

foo(x, d, m);
bar(x, d, m);

Normally, compilers prepare stack frame with arguments before they call a function. In this case the stack will usually be prepared twice: once for each call. But a clever compiler might realize that since these functions do not change their local parameter values (declared with 'const'), the argument set prepared for the first call can be safely reused for the second call. Thus it can prepare the stack only once.

This is a rather rare and obscure optimization, which can only work when the definition of the function is known at the point of the call (either same translation unit, or an advanced globally-optimizing compiler), but sometimes it might be worth mentioning.

It is not correct to say that it is "worthless" or "has no effect", even though with a typical compiler this might be the case.

Another consideration that is worth mentioning is of different nature. There are coding standards out there, which require coders not to change the initial parameter values, as in "don't use parametrs as ordinary local variables, parameter values should remain unchanged throughout the function". This kinda makes sense, since sometimes it makes it easier to determine what parameter values the function was originally given (while in debugger, inside the body of the function). To help enforce this coding standard, people might use 'const' specifiers on parameter values. Whether it is worth it or not is a different question...

AndreyT
I'm afraid this optimization will only be possible if the compiler is able to find out that within the call to `foo` nothing is going to change `x`, `d`, and `m` - which is harder than you might think.
sbi
No, you missed the point. Once you declare the parameter as 'const' (as in my example), the compiler doesn't have to "find out" anything. It can safely assume that within 'foo' nothing can legally change the value of the argument, which is the very point of using 'const' there. If you somehow manage to "hack" the promise given to the compiler by 'const', it is your own fault and the compiler is not responsible for catching that. The behavior is undefined and all bets are off. This is precisely how 'const' works and always worked in C/C++.
AndreyT
I think sbi has aliasing in mind. For all the compiler knows, the implementation of foo has access to a pointer to x (perhaps it's stored in a global, or reached via some other parameter). foo might write to that, with the side-effect of modifying x, even though a (foo's copy of x) is const. Then the value which must be passed to bar is the new value of x, not the old one which was passed to foo. Unless the compiler can rule this out, it can't pass the potentially "stale" copy of x as the parameter to bar. So it is harder than you might think, because aliasing is usually hard to rule out.
Steve Jessop
.. basically if foo writes to any int, unsigned int, or char value via a pointer or reference, or calls any code out of line that does this or can't be analysed, then the optimisation isn't possible. And that's even with strict aliasing rules enabled - without them, if foo writes to anything via any pointer or reference, then you're done for. In both cases, DFA could in theory save the day by proving that in fact the pointer is not an alias, if the compiler can figure out what it does point to, or (more likely) figure out that x, d and m never have their addresses taken.
Steve Jessop
@onebyone: Thanks, you nailed it. (Although I have no idea what "DFA" stands for.) Essentially: _It is possible, but harder than most people think it is._
sbi
You are right. Somehow I missed that simple opportunity: 'foo' can indeed indirectly change value of any of the arguments.
AndreyT
@litb: That's exactly why I said in my original post that the *definition* of the function must be visible at the point of the call. I.e. the compiler must be able to see the function signature used in the *definition*.
AndreyT
Yeah i'm sorry i noticed it just some minutes ago and deleted my comment :) Cheers
Johannes Schaub - litb
Btw, DFA stands for Deterministic Finite Automata.Phew, so late for the party ;)
legends2k
+1 For your answer!
Partial
+1  A: 

Second variant is better. In the first one you can accidently change variable age.

Sergey
Maybe you need to change it without creating another variable.
Justicle
+2  A: 

You should use const on a parameter if (and only if) you would use it on any other local variable that won't be modified:

const int age_last_year = age - YEAR;

It's sometimes handy to mark local variables const where possible, since it means you can look at the declaration and know that's the value, without thinking about intermediate code. You can easily change it in future (and make sure you haven't broken the code in the function, and maybe change the name of the variable if it now represents something slightly different, which is changeable, as opposed to the previous non-changing thing).

As against that, it does make the code more verbose, and in a short function it's almost always very obvious which variables change and which don't.

So, either:

void MyFunction(const int age, House &purchased_house)
{
    const int age_last_year = age - YEAR;
}

or:

void MyFunction(int age, House &purchased_house)
{
    int age_last_year = age - YEAR;
}
Steve Jessop
A: 

Here are some great articles and a book I found explaining the advantages of using const:


Can I propose the following maxim to you?

If an object/variable can be qualified has being constant, it should be. At worst, it will not cost anything. At best, you will be documenting the role of the object/variable in your code and it will allow the compiler the opportunity to optimize your code even more.

Some compilers neglect to exploit the potential of optimization with the use of 'const' and that has lead many experts to neglect the use of constant parameters by value when it could be used. This practice takes more strictness, but it will not be harmful. At worst, you do not lose anything , but you do not gain anything too and at best, you win from using this approach.


For those who do not seem to understand the utility of a const in a by value parameter of a function/method... here is a short example that explains why:

.cpp

void WriteSequence(int const *, const int);

int main()
{
    int Array[] = { 2, 3, 4, 10, 12 };
    WriteSequence(Array, 5);
}


#include <iostream>
using std::cout;
using std::endl;
void WriteSequence(int const *Array, const int MAX)
{
    for (int const * i = Array; i != Array + MAX; ++i)
      cout << *i << endl;
}

What would had happen if I would had removed the const in front of int MAX and I had written MAX + 1 inside like this?

void WriteSequence(int Array[], int MAX)
{
    MAX += MAX;
    for (int * i = Array; i != Array + MAX; ++i)
      cout << *i << endl;
}

Well your program would crash! Now, why would someone write "MAX += MAX;" ? Perhaps human error, maybe the programmer was not feeling well that day or perhaps the programmer simply did not know how to write C/C++ code. If you would have had const, the code would have not even compiled!

Safe code is good code and it does not cost anything to add "const" when you have it!


Here is an answer from a different post for a very similar question:

"const is pointless when the argument is passed by value since you will not be modifying the caller's object."

Wrong.

It's about self-documenting your code and your assumptions.

If your code has many people working on it and your functions are non-trivial then you should mark "const" any and everything that you can. When writing industrial-strength code, you should always assume that your coworkers are psychopaths trying to get you any way they can (especially since it's often yourself in the future).

Besides, as somebody mentioned earlier, it might help the compiler optimize things a bit (though it's a long shot).

Here is the link: answer.

Partial
Well i/we agree it's *not* pointless to write const for value parameters. It may also add safety. Why do people write raw C code, when they could use java and be "safer"? Because C is fast, and C is lowlevel. Safety is not everything - there are other concerns like readability, clarity. Your main point in this answer is that "const" is useful - i think we all agree. But sticking "const" *anywhere* - that's what we disagree about. I don't quite get your first two links - they talk about "const" in general, not about "const" for value parameters on the toplevel in particular
Johannes Schaub - litb
And i think this discussion will never end. You have your opinion, which has a well reflected background, and i have my opinion, which also has a well reflected background. Neither of us, i suspect, will "convert" to the other's guy opinion, and so i suspect about most other people involved in this discussion.
Johannes Schaub - litb
@litb: For the first link have a look at the conclusion and for the second link it says to put a const when you can. It is more or less a standard from where I am from to use const and it will finish off my making one's code cleaner.
Partial
@litb: Could you elaborate on why it is not readable to write a const for a data type in a passed by value parameter? If I remember correctly, you will not gain any performance or barely any from passing by reference a primitive data type such as an integer since it will implicitly create a pointer on the integer in order for you to be able to use the variable or constant declared outside of the function/method. Therefore, using a passed by value constant will not create any problem.
Partial
You start with main: `int main(int const argc, char ** const argv) { ... }` and put const *anywhere* just for the joy of putting const. I can see how that ends up with a mess. :) I'm not going to say i will never put it - but i won't put it just because some people on usenet say "go put it anywhere".
Johannes Schaub - litb
See, this is something i won't be able to convince you, i think. It's a *taste*: You like to have them const, and i like to have them non-const in the general case. They are not traditional constant in that they are set once and then remain constant to me. But they are parameters - values handed over by a caller - it's a different concept and i've developed a different understanding of them. I would say we keep it at this, and accept each other's opinion.
Johannes Schaub - litb
Also, did you notice that you made "Array" non-const? If you apply your rule consistently, you should write `void WriteSequence(int * const Array, const int MAX)` - this is just one example how it also goes against your own intuition, apparently. In my code, the function looks like `void WriteSequence(int const *Array, int Max)`.
Johannes Schaub - litb
Duly noted. I was targeting primitive types and not really pointers since the OP did not ask about pointers.
Partial
Well now your code is ill-formed :) (you're calling an undefined function) The const before the star is not ignored because it's significant to the caller because it will determine whether the called function can change data of the caller. Only toplevel const is ignored for declaration matching. You have to put that `const` at both the definition and the declaration.
Johannes Schaub - litb
Why aren't you following your advice in your example? If you did, it would be `void WriteSequence(int const* const Array, const int MAX)`.
Roger Pate