constexpr when applied to pointers doesn't imply const
constexpr always implies (top-level) const.
In @seeplus's second example the second const is redundant, it is implied by constexpr.
The types of both mystrw and mystr1 are the same and both variables are usable in constant expressions.
sorry for being late replying, guys..
been busy lately... (well, sometimes i forgot abt this thread)
i haven't read all the replies, so i'll read it later..
As an additional example char const*
has no top-level const-qualifiers - there is a const but not at the top-level, while char const* const
is top-level qualified.
once again, i'm really sorry for the very late reply coz i'm (always) pretty busy
so, guess i'll start with keskiverto's reply
keskiverto wrote:
Lets rephrase:
T ********sample;
(okay, that's really deep pointer to pointer to ...)
If we want that the concrete object fo type T is treated as constant, then we write:
T const ********sample;
but, we may use the alternate syntax:
const T ********sample;
However, if any of those asterisks has to be const-qualified, then the qualifier must be on the right side of that asterisk; there is no alternate syntax for that.
T *** * const ****sample;
Both the T and asterisks can be const-qualified.
T const *** * const ****sample;
i don't know that pointers can be that deep!! how deep actually pointers can be??
int foo;
int bar;
int* gaz = &foo; // gaz points to foo
gaz = &bar; // gaz can be modified to point elsewhere
int* const hue = &foo; // hue points to foo
hue = &bar; // error: cannot modify const pointer
*hue = 42; // ok: can modify pointed to object
Sometimes we want to be sure that a pointer "stays on target".
Defining your functions this way where ever possible ensures that pointer is modified within function body only if we really want it, ex. allocation or initialization of a pointer.
For example you don't have to debug whether some function might have done something to pointer because you make it const by default, which adds value to const correctness in you codebase.
int foo;
int bar;
int* gaz = &foo; // gaz points to foo
gaz = &bar; // gaz can be modified to point elsewhere
int* const hue = &foo; // hue points to foo
hue = &bar; // error: cannot modify const pointer
*hue = 42; // ok: can modify pointed to object
Sometimes we want to be sure that a pointer "stays on target".
yes, i alrdy understand abt this
what i'm asking is this:
However, if any of those asterisks has to be const-qualified, then the qualifier must be on the right side of that asterisk; there is no alternate syntax for that.
T *** * const ****sample;
Both the T and asterisks can be const-qualified.
T const *** * const ****sample;
what do you mean with "asterisks has to be const-qualified"? is the "*" has to be separated by space (" ") ?
Seriously, I haven't looked into the standard to see if there is a limit. If one has multiple levels of pointers, then we are starting to get into C programming style. And one might have 2 levels to do a 2d array (in C), but more than that one should probably be using one of the common data structures IMO. In C++ we have a bunch of containers all ready to go, and they can be nested, and memory management is done by the compiler.
This describes further restrictions on multi level pointers:
int* const some_var // constant pointer to modifiable int, pointer cannot be made to point at something else
So those two examples are different.
In my mind a C++ reference is like a constant pointer but perhaps wrapped up in some Template Meta Programming (TMP) code. I have said that before a long time ago, no one complained then, hopefully that means that the statement is correct :+)
I don't think in practice I have ever gone more than 3 deep. And in reality, that was a 2d array of C style strings. Even in C you won't go past 3-4 dimensions very often. Every extra dimension costs you if the memory is not one solid block, and viewing a solid block in more than 4D is just highly unusual.