Peter
Peter

Reputation: 393

Passing const pointers by ref is better than by value?

When passing a parameter representing a constant buffer of data, is it best to pass by ref? For example a string could be passed as const char * const indicating that both the pointer and the content are constant.

But would const char * const & be better? I have recently seen material stating that passing const values by value is misleading since a copy is made anyway, so in a perverse way passing the const pointer by val would be misleading? If the pointer is to be const it should be passed by ref and therefore const char * const & would be best?

Upvotes: 1

Views: 221

Answers (2)

msam
msam

Reputation: 4287

const char* const x means x is a constant pointer to a constant char

const char* const & x means that x is a reference to a constant pointer to a constant char

The first one passes the pointer, the second a reference to the pointer. In terms of possible use within the function in both cases x acts as a read-only char pointer.

EDIT in response to OP'S comment: you might be mixing up const correctness and advantages of passing by reference.

const int* x (equivalent to int const* x) is a pointer to a constant int, the value of the int cannot be changed through the pointer. In other words you can do x = (int*)y (value of x will change only in the scope of function) but not *x = 1.

const int& x (equivalent to int const& x) means x is a reference to a constant int. You cannot do x = 1

const int x means that x is a const int. This basically amounts to x being read only. x is a copy of another int so if we remove the const and modify x it would only be modified within the scope of the function. I do not see why someone would object to the const in this case. This is used to avoid programming mistakes like assigning x to some other value then using it again having forgotten about the change in value.

Using const int& x instead of const int x only makes sense if x is an object to avoid making a copy. For the same purpose we could also use const int* const x.

Using const int* const &x instead of const int* const x has the same effect but there are caveats. For instance, if you do this, x can be null! This in itself can be confusing since normally you would expect a value passed by reference to be guaranteed to be non-null. However in this case the reference can be to a null-pointer which would result in an exception if we try to dereference. Dereferencing a null pointer, of course, also results in an exception but this is well-known. As yet I do not see any advantage whatsoever of using const int* const &x.

int * const x is not equivalent to const * const &x. int * const x means that the pointer is const, but we can change the value of x (ie we can do *x = 3)

Upvotes: 1

Mushy
Mushy

Reputation: 2645

When passing by reference, as you stated, no copy is supplied as an argument but rather is bound through the reference.

It is important to understand that reference parameters that are not changed inside a function should be references to const.

A common mistake programmers make is to define parameters that a function does not change as plain old references. However, doing so will give the functions's caller the misleading impression that the function might change its argument's value. It is better to use a reference to const, where applicable, because a plain reference unduly limits the type of arguments that can be used with the function.

Where applicable because if you desire to change the argument then it should not have a const reference parameter.

Also, similar to areference to const, a pointer to const says nothing about whether the object to which the pointer points is const. Defining a pointer to const only affects what we can do with the pointer.

There is also the notion of top-level const and low-level const with respect to pointers. A top-level const indicates the pointer itself is a constwhereas if a pointer points to a const, that const pointed to is referred to as a low-level const.

Upvotes: 0

Related Questions