-2

Is there any justified reason why you should use a constant pointer to a constant value in C++? I don't get the reason behind it at all because in the src-directory someone gave me they don't even try to write to the var, they just read a value from it.

Is it something like a convention always to use constant pointers to constant vars even if you only need them once for reading?

bool
serialize_state(int const fd, game_state const * const state) { ... }

=> constant pointer to constant game_state in saved "state", right?

phip1611
  • 5,460
  • 4
  • 30
  • 57
  • 5
    *they don't even try to write to the var, they just read a value from it* What would be the easier way to know that fact? Finding const in the signature or by analyzing the entire method (and all methods it in its turn passes things to) for writes? It also means that you can safely call it with a constant, since it can't be written to. – Joachim Isaksson Mar 25 '16 at 12:09
  • The question stands the other way round: why *not* use a read-only type if you just read data? You cannot really use a read-only type when writing, can you? – Angew is no longer proud of SO Mar 25 '16 at 12:37

3 Answers3

2

a const pointer to a const value guarantees that a client can neither change the value nor change the pointer (so that it points to something different). When applicable, this approach has several advantages:

  • is safer and less error/bug-prone, since it is impossible (or at least difficult) to alter parts of the program that you shouldn't.
  • as Joachim Isaksson mentioned in his comment, it makes it possible to safely call certain functions with constant values (since you the function is guaranteed not to try altering them)
  • when used as function arguments, it is possible to pass temporary values to them
  • it makes intentions explicit through code (rather than through comments), so that certain errors can be caught at compile-time

I can't see any real disadvantage really, so my advice would be: always use them when you do need raw pointers to the same const object. That said, I'd advice against using raw pointers anyway now that std::unique_ptr and std::shared_ptr are part of the standard.

Marinos K
  • 1,779
  • 16
  • 39
1

In almost all cases, making variables const when possible is a Good Thing (tm) as it expresses intent and reduces the chance of misuse.

When passing arguments however, there is a caveat.

passing a pointer or reference to a const resource is sensible and correct:

void foo(const char* text);    
void foo(const std::string& text);

But when passing an actual copy as an argument, making it const has a number of drawbacks. Consider:

std::string sorted(const std::string source)
{
    // I must copy source again because it's immutable
    auto result = source; // redundant copy
    std::sort(std::begin(result), std::end(result));
    return result;
}

whereas passing a mutable argument allows the function to use it more efficiently:

std::string sorted(std::string source)
{
    // lots of opportunity for copy elision and RVO here.
    std::sort(std::begin(source), std::end(source));
    return source;
}

To address the specific question of whether this is good form:

void foo(const char* const text);

The answer is a qualified, "NO" because:

  1. the second const provides no guarantees to anyone. The called function could simply copy the pointer text and modify the copy.

  2. It clutters the API with another word, while adding no value.

BUT There is a counter-argument that the second const is not there for the benefit of the caller, but for the implementor of foo().

In this case, it provides him with a safe const pointer to const data which he can use without accidentally changing.

The counter-counter argument to that is that all this does is leak implementation details through the interface.

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • Regarding your points 1 and 2, there is reportedly at least one code analysis tools (I think it was an IDE) that just doesn't understand that top-level `const` doesn't influence the signature, and so will complain if the implementation has a top-level `const` where the declaration does not. Such a tool issue can be a good practical reason to use top level `const` also in the declaration. – Cheers and hth. - Alf Mar 25 '16 at 12:47
  • such a tool issue can be a good practical reason to *not use that tool* – M.M Mar 25 '16 at 13:06
0

const lets you see at a glance that a variable is not modified in the following code. So it helps with understanding the code, more quickly or at all. And so the general advice is to sprinkle const generously all over the code, wherever it can be used.

C++11 move semantics conflict with that advice. For example, if a function takes a string argument and just stores the value somewhere, then the formal argument should better not be const, so that it can be efficiently moved from. In my opinion there is a missing language feature here, a way to say that after this point, the variable can not and will not be used, so that the compiler knows, and so that it can be logically const over the range of code where it does carry a useful value.

That is, C++ does not fully support even the limited kind of constness that it provides via the const and constexpr keywords. And that's a shame. But even if one cannot easily use const in all situations where it's desirable (because it prevents the move optimization), good programmers will as a matter of course use it anywhere it doesn't conflict with other concerns, because nearly all constraints on the possible effects of code, help to understand and maintain that code.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331