In C programming language, *p represents the value stored in a pointer and p represents the address of the value, is referred as a pointer. const char* and char const* says that the pointer can point to a constant char and value of char pointed by this pointer cannot be changed.
Yes it is allowed.
The difference is that const char * is a pointer to a const char , while char * const is a constant pointer to a char . The first, the value being pointed to can't be changed but the pointer can be. The second, the value being pointed at can change but the pointer can't (similar to a reference).
C. NOTE: There is no difference between const char *p and char const *p as both are pointer to a const char and position of '*'(asterik) is also same.
I had this same problem a few years ago and it irked me to no end.
The rules in C are more simply stated (i.e. they don't list exceptions like converting char**
to const char*const*
). Consequenlty, it's just not allowed. With the C++ standard, they included more rules to allow cases like this.
In the end, it's just a problem in the C standard. I hope the next standard (or technical report) will address this.
To be considered compatible, the source pointer should be const in the immediately anterior indirection level. So, this will give you the warning in GCC:
char **a;
const char* const* b = a;
But this won't:
const char **a;
const char* const* b = a;
Alternatively, you can cast it:
char **a;
const char* const* b = (const char **)a;
You would need the same cast to invoke the function f() as you mentioned. As far as I know, there's no way to make an implicit conversion in this case (except in C++).
However, in pure C, this still gives a warning, and I don't understand why
You've already identified the problem -- this code is not const-correct. "Const correct" means that, except for const_cast
and C-style casts removing const
, you can never modify a const
object through those const pointers or references.
The value of const
-correctness -- const
is there, in large part, to detect programmer errors. If you declare something as const
, you're stating that you don't think it should be modified -- or at least, those with access to the const
version only should not be able to modifying it. Consider:
void foo(const int*);
As declared, foo
doesn't have permission to modify the integer pointed to by its argument.
If you're not sure why the code you posted isn't const
-correct, consider the following code, only slightly different from HappyDude's code:
char *y;
char **a = &y; // a points to y
const char **b = a; // now b also points to y
// const protection has been violated, because:
const char x = 42; // x must never be modified
*b = &x; // the type of *b is const char *, so set it
// with &x which is const char* ..
// .. so y is set to &x... oops;
*y = 43; // y == &x... so attempting to modify const
// variable. oops! undefined behavior!
cout << x << endl;
Non-const
types can only convert to const types in particular ways to prevent any circumvention of const
on a data-type without an explicit cast.
Objects initially declared const
are particularly special -- the compiler can assume they never change. However, if b
can be assigned the value of a
without a cast, then you could inadvertently attempt to modify a const
variable. This would not only break the check you asked the compiler to make, to disallow you from changing that variables value -- it would also allow you break the compiler optimizations!
On some compilers, this will print 42
, on some 43
, and others, the program will crash.
Edit-add:
HappyDude: Your comment is spot on. Either the C langauge, or the C compiler you're using, treats const char * const *
fundamentally differently than the C++ language treats it. Perhaps consider silencing the compiler warning for this source line only.
This is annoying, but if you're willing to add another level of redirection, you can often do the following to push down into the pointer-to-pointer:
char c = 'c';
char *p = &c;
char **a = &p;
const char *bi = *a;
const char * const * b = &bi;
It has a slightly different meaning, but it's usually workable, and it doesn't use a cast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With