const variable syntax

Pages: 123
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.

1
2
3
4
5
#include <concepts>
constexpr const char*  mystr1 {"foobar1"};
constexpr const char* const mystrw {"foobar2"};
static_assert(std::same_as<decltype(mystr1), decltype(mystrw)>);
static_assert(std::same_as<decltype(mystr1), char const* const>);
Last edited on
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..

constexpr always implies (top-level) const.

what do you mean with top-level const..?
There are a couple decent explanations on the internet
https://stackoverflow.com/questions/7914444/what-are-top-level-const-qualifiers

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.
Last edited on
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??

asterisks has to be const-qualified


what do you mean with this?
hello..?
1
2
3
4
5
6
7
8
9
10
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".
One other case where we want to make sure pointer stays on target is when passed as function parameter:

1
2
3
4
5
void foo(int* const param)
{
      *param = 3; // OK
      param = nullptr; // error
}


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.
Last edited on
keskiverto wrote:
1
2
3
4
5
6
7
8
9
10
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 (" ") ?
I don't say "has to". I say "if ..., then ...". The "has to" should probably expand to "has to be const for the purpose of the code".

int * const hue = &foo;

Here the pointer is const. The * (asterisk) is const-qualified.

Space is optional, there to make reading easier.
Last edited on
@chipp

Also understand the difference between "top level const" and "low level const", and you'll be a better programmer.
I don't say "has to". I say "if ..., then ...". The "has to" should probably expand to "has to be const for the purpose of the code".

int * const hue = &foo;

Here the pointer is const. The * (asterisk) is const-qualified.

Space is optional, there to make reading easier.


actually, my question is your quotes sounds like you make the asterisk become const... but, now i understand that what you mean is constant reference

what about my question..?
how deep actually pointers can be??


also, how const works, actually..? i mean, it can, apparently, written like this:

 
int const* some_var {&some_ref};


and this!

 
int* const some_var {&some_ref};


it's confusing, imo

@malibor: i'll look into it... thx..
Last edited on
seriously..?? no replies...??
how deep actually pointers can be??


Until one gets confused.

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:

https://en.cppreference.com/w/cpp/language/implicit_conversion#Qualification_conversions

it's confusing, imo


Read from right to left:

int const* some_var // pointer to const int

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 :+)
So those two examples are different.

then, how about this..? how it should be read..?

T **** const ****sample;

hopefully that means that the statement is correct :+)

haha...
then, how about this..? how it should be read..?

T **** const ****sample;


TheIdeasMan wrote:

Read from right to left:


But why do you want to mess with such stuff?

TheIdeasMan wrote:
Until one gets confused.
declare sample as pointer to pointer to pointer to pointer to const pointer to pointer to pointer to pointer to class T
https://cdecl.org/?q=class+T+****+const+****sample%3B
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.
But why do you want to mess with such stuff?

it wasn't me...
https://www.cplusplus.com/forum/beginner/279350/#msg1206988

I don't think in practice I have ever gone more than 3 deep.

+1

@jonnin: wdym with "solid block"? you mean just a "block memory"?
Last edited on
phew... why do i always have to bump the thread first?
wdym with "solid block"?


He means contiguous memory.

Allocating memory is a relatively expensive operation: if it has to be done more than once, then that is more expense in time.
Pages: 123