cppbestpractices icon indicating copy to clipboard operation
cppbestpractices copied to clipboard

Const as Much as Possible (Not!)

Open tad-ashlock opened this issue 5 years ago • 3 comments

While "Const as Much as Possible" is generally good practice, const should not be directly used on function declaration parameters, including member functions.

A quick example:

void foo (int x);
void foo (int const x) {return x * 2;}

void bar (char const * s);
void bar (char const * const s) {puts(s);}

Notice I said "directly". Hence s isn't const in the declaration, but is in the definition (direct), but what s points at is const in both, and must match in both (indirect).

The reason for doing this is to not leak a function's implementation details. Because whether a function treats a parameter variable as const or not is an implementation detail of the function. And if a function gets modified such that its parameter is no longer treated as const, then callers of that function shouldn't have to be recompiled.

This is a difference between C and C++. In C, the function definition's parameter type(s) must exactly match that of the function declarations. (At least it used to. I haven't actually developed anything significant with modern C.)

tad-ashlock avatar Nov 18 '20 11:11 tad-ashlock

Dan Saks gives a better, and more thorough, description of this topic in the article "Top-Level cv-Qualifiers in Function Parameters" [PDF]. What I called "direct", he calls "top-level".

tad-ashlock avatar Nov 18 '20 18:11 tad-ashlock

I assume you mean only for parameters passed "by value"? if the parameter is pass by reference then surely const is not an implementation detail, right?

IgnacioJPickering avatar Aug 05 '21 01:08 IgnacioJPickering

Yes. But just to be explicit in our agreement about where const is applied: a parameter of reference type at the top level can't be const-qualified, since it's inherently const and can't be reseated. So whether that would be an implementation detail or not isn't really up for discussion. On the other hand, the target of a parameter of reference type can be const-qualified or not. But that's not the "direct" or "top-level" type, so that is not an implementation detail and therefore the declaration and definition must match there.

tad-ashlock avatar Aug 05 '21 11:08 tad-ashlock