Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
// with const
// const communicates the fact that the implementation of foo() does not modify parameter i
void foo(const int i)
// implementation of foo()
From the caller's perspective, though, both versions are identical (have the same signature). The value of the argument passed to
foo()
is copied.
foo()
might change that copy, not the value passed by the caller.
This is all well, but one is allowed to use
const
also when
declaring
foo()
:
void foo(int i); // normal way to declare foo()
void foo(const int i); // unusual way to declare foo() - const here has no meaning
Why is const allowed by the C and C++ standards when declaring foo(), even though it is meaningless in the context of such a declaration? Why allow such a nonsensical use of const?
const is a type qualifier: https://en.cppreference.com/w/cpp/language/cv
As such, they can be added to a type as part of the grammar itself. I suppose they didn't want to specify differently an argument and a variable. (it makes probably the implementation a little bit easier?)
Then the issue is that they don't participate to the signature when they refer to the argument itself (they are part of the signature when they refer for instance to the memory pointed by the argument), as you said in your question.
clang-tidy has a rule to remove the superfluous const: https://clang.llvm.org/extra/clang-tidy/checks/readability-avoid-const-params-in-decls.html
There is no reason to forbid qualifiers on function parameters in non-definition declarations, and allowing it allows source code to keep identical declarations in both the definition and any non-definition declarations.
In a definition, const and other qualifiers have their normal effects, as in:
int foo(const int x)
x = 3; // Not permitted.
Presuming we do not wish to lose this behavior, permitting qualifiers in definitions while prohibiting them in declarations that are not declarations would unnecessarily complicate the standard. Additionally, it means humans who copied the definition to paste it elsewhere as a non-definition declaration would have to make additional edits, and any software designed to collect external definitions from a source file to create a header file containing non-definition declarations would have to do additional parsing and manipulation to strip qualifiers (but only top-level qualifiers as in int * const p, where the const qualifies p, not those internal to types, as in const int *p, where the const, qualifies the type p points to, not p).
Generally, the C and C++ language do not prohibit “useless” things, such as adding a constant zero (which could arise from a combination of preprocessor macros, where some expression happens to evaluate to zero for certain selections of build options), isolated empty statements, and so on. These things are not of concern unless they contribute to the human propensity to make errors. For example, if adding zero always happened as a result of a mistake (so it never happened as a consequence such as mentioned above) then prohibiting it could have value. However, if there is no value to prohibiting something, then expending effort on prohibiting it is wasteful.
–
First, const in lis of paramateres of functions isn't meaningless. Consider this code:
void foo(int i)
std::cout << i << "\n";
That's not possible if you add const. A parameter passed by value is a local variable for function if it is passed by value. Declaring it const you tell compiler that variable i cannot change its value during its lifetime.
Still not much of use? In C, maybe. In C++ that also means that you cannot call non-const methods of the type-class passed by value. Let's suppose that argument can be an object of a class-type and is an interface to some object that is stored outside of function. Then it does make sense that you declare that your function must leave that object "immutable".
Const doesn't participate in this particular case to form a function signature, so encountering those two variants in same scope or during name look-up leads to an ill-formed program. In other case it may define difference in categories of argument's value.
–
–
–
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.