How far do you go with const
? Do you just make functions const
when necessary or do you go the whole hog and use it everywhere? For example, imagine a simple mutator that takes a single boolean parameter:
void SetValue(const bool b) { my_val_ = b; }
Is that const
actually useful? Personally I opt to use it extensively, including parameters, but in this case I wonder if it's worthwhile?
I was also surprised to learn that you can omit const
from parameters in a function declaration but can include it in the function definition, e.g.:
.h file
void func(int n, long l);
.cpp file
void func(const int n, const long l)
Is there a reason for this? It seems a little unusual to me.
There's really no reason to make a value-parameter "const" as the function can only modify a copy of the variable anyway.
The reason to use "const" is if you're passing something bigger (e.g. a struct with lots of members) by reference, in which case it ensures that the function can't modify it; or rather, the compiler will complain if you try to modify it in the conventional way. It prevents it from being accidentally modified.
Being a VB.NET programmer that needs to use a C++ program with 50+ exposed functions, and a .h file that sporadically uses the const qualifier, it is difficult to know when to access a variable using ByRef or ByVal.
Of course the program tells you by generating an exception error on the line where you made the mistake, but then you need to guess which of the 2-10 parameters is wrong.
So now I have the distasteful task of trying to convince a developer that they should really define their variables (in the .h file) in a manner that allows an automated method of creating all of the VB.NET function definitions easily. They will then smugly say, "read the ... documentation."
I have written an awk script that parses a .h file, and creates all of the Declare Function commands, but without an indicator as to which variables are R/O vs R/W, it only does half the job.
EDIT:
At the encouragement of another user I am adding the following;
Here is an example of a (IMO) poorly formed .h entry;
The resultant VB from my script;
Note the missing "const" on the first parameter. Without it, a program (or another developer) has no Idea the 1st parameter should be passed "ByVal." By adding the "const" it makes the .h file self documenting so that developers using other languages can easily write working code.
Ah, a tough one. On one side, a declaration is a contract and it really does not make sense to pass a const argument by value. On the other hand, if you look at the function implementation, you give the compiler more chances to optimize if you declare an argument constant.
I use const on function parameters that are references (or pointers) which are only [in] data and will not be modified by the function. Meaning, when the purpose of using a reference is to avoid copying data and not to allow changing the passed parameter.
Putting const on the boolean b parameter in your example only puts a constraint on the implementation and doesn't contribute for the class's interface (although not changing parameters is usually advised).
The function signature for
and
is the same, which explains your .c and .h
Asaf
I know the question is "a bit" outdated but as I came accross it somebody else may also do so in future... ...still I doubt the poor fellow will list down here to read my comment :)
It seems to me that we are still too confined to C-style way of thinking. In the OOP paradigma we play around with objects, not types. Const object may be conceptually different from a non-const object, specifically in the sense of logical-const (in contrast to bitwise-const). Thus even if const correctness of function params is (perhaps) an over-carefulness in case of PODs it is not so in case of objects. If a function works with a const object it should say so. Consider the following code snippet
ps.: you may argue that (const) reference would be more appropriate here and gives you the same behaviour. Well, right. Just giving a different picture from what I could see elsewhere...
On compiler optimizations: http://www.gotw.ca/gotw/081.htm