Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ * const *const

I tried to search answer for this but I found it very hard to find 'exact' example of this kind. I understand very little about pointers to pointers and I feel there is something more laying under the skin of this than just pointer to something.

So how would you guys translate this?

void free(shame_1 * const * const group_1);

Am I right if I translate it as const group_1 pointer to const pointer to shame_1?

Thanks.

like image 514
matti marvi Avatar asked Feb 13 '14 07:02

matti marvi


People also ask

What is const * const in C?

const int* const is a constant pointer to constant integer This means that the variable being declared is a constant pointer pointing to a constant integer. Effectively, this implies that a constant pointer is pointing to a constant value.

What does const char * const mean?

const char* const says that the pointer can point to a constant char and value of int pointed by this pointer cannot be changed. And we cannot change the value of pointer as well it is now constant and it cannot point to another constant char.

What is the difference between const char * and char * const?

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).

Is const better than #define in C?

In general, const is a better option if we have a choice and it can successfully apply to the code. There are situations when #define cannot be replaced by const. For example, #define can take parameters (See this for example). #define can also be used to replace some text in a program with another text.


2 Answers

shame_1 * const * const group_1;

declares a variable named group_1, whose type is a const pointer (you cannot change where it points at) to another const pointer (same) to a shame_1-type object, whose value you can actually change.

So, for instance, you cannot compile:

group_1 = nullptr;
*group_1 = nullptr;

You can, however, do:

void f(shame_1& group) {
    //stuff that modifies group
    ...
}
f(**group1);

As zakinster commented, having a look at the spiral rule should help you understand this kind of notation.

like image 77
Martin J. Avatar answered Sep 30 '22 00:09

Martin J.


Generally, just read from right to left:

void free(shame_1 * const * const group_1);

free takes a parameter called group_1 that's a const pointer to a const pointer to a shame_1 object.

  • It's not relevant here, but the main hassle reading right-to-left is that some people use T const * and others use const T* and they mean the same thing, so whether you see either T const or const T you should read it as const T. In your code, only the pointers are const anyway.

For example:

shame_1 a_shame;
const shame_1* p_a_shame = &a_shame;
free(&p_a_shame);

There's very little utility in this... free() could have accepted a const pointer to a shame_1 without an extra level of indirection, and would still have been able to do all the same things to the shame_1, so it's only useful if free() has to pass the const-pointer-to-const-pointer to some other function (with ultimately there being no good reason for the whole mess).

You can visualise the memory usage / relationships as:

[a_shame]  <------ [p_a_shame]  <------  [group_1]*
  • this is likely only in a CPU register, though the others may be too after optimisation.

Am I right if I translate it as const group_1 pointer to const pointer to shame_1?

So, to me the "const group_1 pointer" bit is a bit suspect... I think it reads better as "group_1 is a const pointer to..." or "const pointer (called group_1) to...".

like image 33
Tony Delroy Avatar answered Sep 29 '22 23:09

Tony Delroy