Qual é o significado de vários qualificadores const?
-
21-12-2019 - |
Pergunta
Código:
const char* const* const* foo(int bar);
Já vi consts duplos que também impedem a modificação do ponteiro.Primeira vez que vi const triplo na minha vida.Quer saber qual é a sua utilidade.
Solução
No seu exemplo, todos, exceto o nível superior de indireção, todos const
qualificado.
const char /* const qualified base level */
*const /* const qualified level 1 */
*const /* const qualified level 2 */
* /* regular level 3 */
foo(int bar);
foo
é uma função que aceita um int
argumento e retorna um ponteiro regular.
O ponteiro que ele retorna aponta para um const
ponteiro qualificado
o que, por sua vez, aponta para outro const
ponteiro qualificado
que aponta para const
qualificado char
Outras dicas
Se você tiver um ponteiro multinível, terá várias variáveis de ponteiro.Exemplo:
char*** foo;
é acessado assim:
| foo | pointer1 | pointer2 | string |
| ^ | ^ | ^
\___/ \___/ \___/
Você pode qualificar cada um dos quatro locais na memória como sendo const
, como na declaração
const char *const *const *const foo;
No entanto, é melhor evitar se tornar um programador três estrelas.
Hah - a confusão ao redor const
.
Basicamente, se qualificar um ponteiro, então se aplica ao ponteiro imediatamente à sua esquerda.Por exemplo:
char *const c;
faz c
um ponteiro somente leitura para char
, enquanto
const char *c;
Faz c
um ponteiro para um somente leitura char
, embora você possa alterar onde c
aponta para.
É claro que tanto o ponteiro quanto o que ele aponta podem ser somente leitura:
const char *const c;
Isto faz c
um ponteiro somente leitura para um somente leitura char
.Com a declaração anterior, você pode modificar *c
, mas você não pode modificar c
(ou seja,você não pode apontar para outro lugar).Com o segundo, você pode atribuir a c
mas não para *c
, e com o terceiro, você não pode modificar para onde ele aponta, nem pode modificar o objeto apontado.
Isso se estende a vários níveis de indireção.Para o seu caso, você pode querer reagrupar o const
palavras-chave com o ponteiro correspondente de que estão se qualificando.Este é principalmente um problema de espaços em branco, mas seria assim:
const char *const *const *foo(int bar);
Que faz foo
retornar um ponteiro para um ponteiro somente leitura para um ponteiro somente leitura para um ponteiro somente leitura char
.Leia isso com atenção:observe que, dado este trecho de código:
const char *const *const *ptr = foo(0);
Então você sabe que atribuir a ptr
é legal, mas qualquer outra atribuição é ilegal, ou seja, você não pode atribuir a *ptr
, **ptr
, e ***ptr
.
foo
retorna um pointer
que aponta para um constant pointer
que aponta para outro constant pointer
que aponta para um constant char
.Dê uma olhada no regra espiral.
int bar;
const char* const* const* ptr = foo(bar);
Então basicamente você não pode mudar nada *ptr
ou **ptr
ou ***ptr
.