For Programmers: Free Programming Magazines  


Home > Archive > VC Language > November 2005 > const and call by value parameters









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author const and call by value parameters
Mark

2005-11-17, 7:59 am

I have a function

void myobject::g (double d)
{
dval = d;
}

Now function g() doesn't modify it's local copy of d in any way, therefore
it should be declared as

void myobject::g (const double d) {}

The thing is, I find that the vast majority of my call by value parameters
aren't reused within their functions, therefore I find that I have an awful
lot of function parameters using the const modifier.

When I look at other code, in books or in libraries, you don't tend to see
const littered throughout the code, even in functions that don't modify
their value parameters.

Am I missing something here?

--
Best regards
Mark


Arman Sahakyan

2005-11-17, 7:59 am

Hi,



"Mark" wrote:

> I have a function
>
> void myobject::g (double d)
> {
> dval = d;
> }
>
> Now function g() doesn't modify it's local copy of d in any way, therefore
> it should be declared as
>
> void myobject::g (const double d) {}


Actually, you omit const in this case. I use const in case when a funstion
MUST NOT modify its parameter, rather than when it DOESN'T modify
its parameter. Consider the following code;

double dVal = 5;
obj.g(dVal); // your function
// We are sure that dVal is 5 (hasn't been modified), since
// g(double d) doesn't take its parameter as a reference -
// g(double & d);
double dSomeOtherVal = dVal; // 5

So, if g(double d) doesn't disturb the outer stuff, it is its problem
to handle 'd' properly, and since g's body is very simple and you may
see that 'd' doesn't carry mutation before being used, you may simply omit
'const' in the parameter.

Use const with references (or pointers) if the parameter is not supposed
to be changed:

void myobject::g(const double &d);

Practically, such parameters are objects of some classes
that do not have copy constructor, or aren't small enough
to be copied instantly.


> The thing is, I find that the vast majority of my call by value parameters
> aren't reused within their functions, therefore I find that I have an awful
> lot of function parameters using the const modifier.
>
> When I look at other code, in books or in libraries, you don't tend to see
> const littered throughout the code, even in functions that don't modify
> their value parameters.
>
> Am I missing something here?
>
> --
> Best regards
> Mark
>
>




--
======
Arman
David Wilkinson

2005-11-17, 7:59 am

Mark wrote:

> I have a function
>
> void myobject::g (double d)
> {
> dval = d;
> }
>
> Now function g() doesn't modify it's local copy of d in any way, therefore
> it should be declared as
>
> void myobject::g (const double d) {}
>
> The thing is, I find that the vast majority of my call by value parameters
> aren't reused within their functions, therefore I find that I have an awful
> lot of function parameters using the const modifier.
>
> When I look at other code, in books or in libraries, you don't tend to see
> const littered throughout the code, even in functions that don't modify
> their value parameters.
>
> Am I missing something here?
>


Mark:

The real use of const in function prototypes is with reference and
pointer parameters. Here the const indicates a contract with the caller.
If const is present then the parameter will not be changed in the
function, while if it absent there is a presumption that it will (or
might) be changed, because otherwise const should have been used.

The use of const on variables passed by value does not indicate a
contract with the caller, but rather is an implementation detail of the
function. Therefore, personally, I do not like to see const on value
parameters in function prototypes. Also, I think you will find that very
few programmers do this, and so if you do it your function will look
strange to other programmers reading your code.

Personally, I also think it is bad style to change a parameter passed by
value in the body of the function. Don't do this:

void f(double d)
{
if(d < 0.0) d=0.0;
}

but rather this

void f(double d)
{
double dNew = d < 0.0 ? 0.0 : d;
}

So I guess I treat parameters passed by value as if they were const, but
I don't insist on it in the prototype.

David Wilkinson

Gustavo Fernández

2005-11-17, 7:05 pm

> Personally, I also think it is bad style to change a parameter passed by
> value in the body of the function. Don't do this:
>
> void f(double d)
> {
> if(d < 0.0) d=0.0;
> }
>
> but rather this
>
> void f(double d)
> {
> double dNew = d < 0.0 ? 0.0 : d;
> }
>
> So I guess I treat parameters passed by value as if they were const, but I
> don't insist on it in the prototype.


I agree with you, but if you declare those parameters with const, you can
prevent other programmers could modifying the code and use the bad style you
showed before.

I use const as Mark do, and it's true that it could make more difficult the
reading, but I think it's good to avoid code like showed above.


Mark

2005-11-17, 7:05 pm

Maybe there is some compiler optimization that can be done with (const int
i) as opposed to (int i) ?

--
Best regards
Mark

"Gustavo Fernández" <gustavofdez@visualchart.com> wrote in message
news:eXfCqo46FHA.4084@TK2MSFTNGP10.phx.gbl...
>
> I agree with you, but if you declare those parameters with const, you can
> prevent other programmers could modifying the code and use the bad style
> you showed before.
>
> I use const as Mark do, and it's true that it could make more difficult
> the reading, but I think it's good to avoid code like showed above.
>



Doug Harrison [MVP]

2005-11-17, 7:05 pm

On Thu, 17 Nov 2005 11:51:57 -0000, "Mark" <swozz_@hotmail.com> wrote:

>I have a function
>
>void myobject::g (double d)
>{
> dval = d;
>}
>
>Now function g() doesn't modify it's local copy of d in any way, therefore
>it should be declared as
>
>void myobject::g (const double d) {}
>
>The thing is, I find that the vast majority of my call by value parameters
>aren't reused within their functions, therefore I find that I have an awful
>lot of function parameters using the const modifier.
>
>When I look at other code, in books or in libraries, you don't tend to see
>const littered throughout the code, even in functions that don't modify
>their value parameters.
>
>Am I missing something here?


No. Those who like to declare local variables const whenever possible
really ought to do the same for function parameters, but hardly anyone
does. Note that these declare the same function:

void f(double d);
void f(const double d);

So it is possible to put the former in header files but use the latter in
the .cpp file, e.g.

// f.h
void f(double d);

// f.cpp
void f(const double d)
{
...
}

Thus, you can use const function parameters without sacrificing any
readability of the header file.

--
Doug Harrison
Visual C++ MVP
Gustavo Fernández

2005-11-18, 3:58 am

> Maybe there is some compiler optimization that can be done with (const int
> i) as opposed to (int i) ?


I'm not sure if I've understand the question, but if you do

void f ( const int i)
{
i = 1;
...
}

the compiler complains:
[Compiler Error C2166]






Mark

2005-11-18, 7:58 am

The question is "do you use the const modifier if you know the associated
variable is not going to be changed?"

--
Best regards
Mark Baldwin

"Gustavo Fernández" <gustavofdez@visualchart.com> wrote in message
news:eTY%23gpB7FHA.1188@TK2MSFTNGP12.phx.gbl...
>
> I'm not sure if I've understand the question, but if you do
>
> void f ( const int i)
> {
> i = 1;
> ...
> }
>
> the compiler complains:
> [Compiler Error C2166]
>
>
>
>
>
>



Gustavo Fernández

2005-11-18, 7:04 pm

> The question is "do you use the const modifier if you know the associated
> variable is not going to be changed?"


Yes. Personally I think any input parameter should be used for other purpose
than get its value. Using const prevents me and others programmers, who
could modify my rutine, against doing it.


David Wilkinson

2005-11-18, 7:04 pm

Gustavo Fernández wrote:

>
>
> Yes. Personally I think any input parameter should be used for other purpose
> than get its value. Using const prevents me and others programmers, who
> could modify my rutine, against doing it.
>
>


Gustavo:

So would you write

void SomeClass::SomeMethod(const char* const str) const
{

}

? This is just too much const for me!

David Wilkinson

Gustavo Fernández

2005-11-22, 4:01 am

> So would you write
>
> void SomeClass::SomeMethod(const char* const str) const
> {
>
> }
>
> ? This is just too much const for me!


No. Actually I wouldn't do that, but
....SomeMethod(const char * str)...
yes.
Anyway this can be seen as a question of taste.

I prefer:

OtherMethod(const long nSomeNumber)
{
long nSomeNumberCopy = nSomeNumber;
// And then do whatever .....
}

than: (it is a real example I found)

SomeMethod(long nSomeNumber)
{
// Here some original code

// and after a couple of months find code modifying the original like:

while(bCondition)
{
nSomeNumber += nIncrement;
// ...
}
if(nSomeNumber <= MAX_WHATEVER)
{
nSomeNumber = nOtherValue;
}
else
{
nSomeNumber = 0;
}

// ... --> a lot of stuff here

// ... And then remaining original code than asumes that nSomeNumber has
the value it was passed, what of course causes a bug

}

You may be thinking: "any programmer is going to write code like showed
above without analyzing the effects, debugging the changes, bla, bla..,".
That's what I thought some time ago, but after working in a team for a while
I realised the truth. They do it.

PD:
(It's funny, I've realise from your example that last time I used a "char
*" parameter was more than a year ago!)
PD2:
Sorry for my English.

Regards.


David Wilkinson

2005-11-22, 8:02 am

Gustavo Fernández wrote:

>
>
> No. Actually I wouldn't do that, but
> ...SomeMethod(const char * str)...
> yes.
> Anyway this can be seen as a question of taste.
>
> I prefer:
>
> OtherMethod(const long nSomeNumber)
> {
> long nSomeNumberCopy = nSomeNumber;
> // And then do whatever .....
> }

[snip]

Gustavo:

As you say, it is a matter of taste. But when you write

A: void SomeClass::SomeMethod(const char* const str) const

the first const is essential, because it promises the caller that the
contents of str will not be changed (which allows a read-only string to
be passed safely). It is the second const that is like the const in

B: void OtherMethod(const long nSomeNumber)

So if you do B, you should do A.

David Wilkinson
Mark

2005-11-22, 8:02 am

So I guess it depends on who the code's intended audience is...

If you are writing it for the callers benefit, then you omit const as in
(const int localvar) since you are saying nothing interesting to the caller
by telling him that your function doesn't modify its local copy of the var.

If you are writing it for your own benefit, then (const int localvar) can
avoid you making the mistake highlighted by Gustavo above.

--
Best regards
Mark

"David Wilkinson" <no-reply@effisols.com> wrote in message
news:uvse9W17FHA.3752@tk2msftngp13.phx.gbl...
> Gustavo Fernández wrote:
>
> [snip]
>
> Gustavo:
>
> As you say, it is a matter of taste. But when you write
>
> A: void SomeClass::SomeMethod(const char* const str) const
>
> the first const is essential, because it promises the caller that the
> contents of str will not be changed (which allows a read-only string to be
> passed safely). It is the second const that is like the const in
>
> B: void OtherMethod(const long nSomeNumber)
>
> So if you do B, you should do A.
>
> David Wilkinson



Doug Harrison [MVP]

2005-11-22, 8:02 am

On Tue, 22 Nov 2005 13:29:30 -0000, "Mark" <swozz_@hotmail.com> wrote:

>So I guess it depends on who the code's intended audience is...
>
>If you are writing it for the callers benefit, then you omit const as in
>(const int localvar) since you are saying nothing interesting to the caller
>by telling him that your function doesn't modify its local copy of the var.
>
>If you are writing it for your own benefit, then (const int localvar) can
>avoid you making the mistake highlighted by Gustavo above.


Bingo. And you can actually do that when you separate declaration from
definition per my other message in this thread.

--
Doug Harrison
Visual C++ MVP
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com