Inicialização entre os tipos de “int const ** const” e “int **” não é permitido, por quê?

StackOverflow https://stackoverflow.com/questions/1468148

Pergunta

Usando V1.8 z / OS compilador XL C, com avisos levantado-up usando INFO (ALL), eu recebo o seguinte aviso na linha 4 do código abaixo:

WARNING CCN3196 Initialization between types "const int** const" and "int**" 
                is not allowed.


1  int foo = 0;
2  int *ptr = &foo;

3  const int * const fixed_readonly_ptr = ptr;

4  const int ** const fixed_ptr_to_readonly_ptr = &ptr;

Eu não posso envolver minha cabeça em torno de por que estou recebendo este aviso. Se eu posso atribuir um ponteiro int para um ponteiro const para int const (linha 3), então por que não posso atribuir o endereço de um ponteiro int para um ponteiro const para ponteiro para int const? O que eu estou ausente?

Observe o código acima é um exemplo emagreceu apenas mostrando o problema que estou enfrentando em uma pequena quantidade de código. O contexto real é que eu tenho um ponteiro const para ponteiro para struct (struct s const **) e estou passando-o como um argumento para uma função que é parâmetro é definido como um ponteiro const para ponteiro para struct const (const struct s ** const). Isto é porque a função não irá modificar os dados na estrutura (daí o primeiro const) e que não modifica o parâmetro do apontador que mantém sempre o endereço transmitido em (daí o segundo const). O valor do ponteiro apontado pode ser alterado pelo caminho (que é por que não há uma terceira const entre o **).

Foi útil?

Solução

A regra C é que você pode converter um ponteiro para algo para um ponteiro para const alguma coisa, mas que algo tem de ser exatamente o mesmo tipo incluindo const e qualificações voláteis mais abaixo na cadeia.

A razão para esta regra é que se a segunda dessas duas linhas foram autorizados:

int *ptr;

const int ** const fixed_ptr_to_readonly_ptr = &ptr;

então este pode ser usado para quebrar a segurança de tipo sem um elenco.

const int i = 4;

// OK, both sides have type const int *
*fixed_ptr_to_readonly_ptr = &i;

// the value of fixed_ptr_to_readonly_ptr is still &ptr
// the value of ptr is now &i;

*ptr = 5;

// oops, attempt to change the value of i which is const

Outras dicas

É uma violação tipo de segurança. Considere este código (I embaralhadas const em torno de um pouco para torná-lo claro se ele se aplica ao ponteiro ou pointee, mas semanticamente isso significa exatamente a mesma coisa):

int* p = 0;
int const** pp = &p; // presumably ok

int const c = 123;
*pp = &c; // okay, &c is int const*, and *p is int const* lvalue

*p = 666; // okay, *p is int lvalue

// wait, so we just changed the value of (const) c above, with no const_cast!

Esta é uma violação tipo de segurança. Você provavelmente vai querer usar um int const * const * vez. Consulte http://www.parashift.com/c++ -faq-lite / const-correctness.html # faq-18.17

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top