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:
the second const provides no guarantees to anyone. The called function could simply copy the pointer text
and modify the copy.
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.