I'm having difficulties in understanding why C++ behaves in a more "relaxed" way than C when it comes to interpreting and creating types for the parameters of a function.
C does the simplest thing in the world, it sticks with what you write and that's it, C++ on the other hand operates in a twisted way that I can't really comprehend.
for example the popular argv
which is a char* []
when passed to a function becomes char**
and I really don't get why, what I expect and "want" is char * const *
but I got this behaviour instead.
You can also read this article in PDF that talks about this differences between C and C++, the article also ends with this phrase:
Although C++ ignores top-level cv-qualifiers in parameter declarations when determining function signatures, it does not ignore those cv-qualifiers entirely.
and since I can't find this issue online ( Embedded System Programming - February 2000 , and this old issues are free ), I'm wondering what this phrase could possibly mean.
Someone can explain why this behaviour is the way it is in C++ ?
EDIT:
One of my examples is
#include <stdio.h>
void foo(int argc, const char *const *const argv) {
printf("%d %s\n", argc, argv[0]);
}
int main(int argc, char *argv[]) {
foo(argc, argv);
return (0);
}
and if you compile this with gcc 4.8.1
you get the expected error
gcc cv_1.c
cv_1.c: In function ‘main’:
cv_1.c:8:3: warning: passing argument 2 of ‘foo’ from incompatible pointer type [enabled by default]
foo(argc, argv);
^
cv_1.c:3:6: note: expected ‘const char * const* const’ but argument is of type ‘char **’
void foo(int argc, const char *const *const argv) {
^
this output makes implicit the fact that argv
is interpreted as char**
Function arguments can be passed by value or by reference. In the case of by reference there is no top-level qualifier so we can ignore that case.
In the case of by-value parameters, the top-level qualifier affects only the copy, and is completely independent of the original that is used to copy-construct that argument. If the top level qualifier was not dropped from the signature, the following two functions would be valid and different overloads:
Now the question is, given a call to
f(1)
which of the two overloads should be selected? The problem here is that whether the argument is const or not does not affect what it can be constructed from, so the compiler would never be able to resolve which is the correct overload. The solution is simple: in the signature the top level qualifier is dropped and both are the same function.