2008-12-03 20 views
39

sé la regla de dedo para leer las declaraciones de derecha a izquierda y yo estaba bastante seguro de que sabía lo que estaba pasando hasta que un colega me dijo que:¿Qué significa un puntero-puntero const en C y en C++?

const MyStructure** ppMyStruct; 

significa "ppMyStruct es un puntero a un puntero const a una MyStructure (mutable) (en C++).

Hubiera pensado que significaba "ppMyStruct es un puntero a un puntero a un const MyStructure". Busqué una respuesta en la especificación C++, pero aparentemente no soy muy bueno en eso ...

¿Qué significa en C++, y significa lo mismo en C?

Respuesta

60

Su colega está equivocado. Eso es un puntero (no const) a un puntero (no const) a una estructura MyStructure. En C y C++.

+6

También es parte de la razón por la que va a ver a veces la alternativa "ortografía recomendada: const MyStructure * * ppMyStruct; Entonces se puede leer De derecha a izquierda: puntero al puntero para const Mystructure. –

+0

¿Quién lee RTL? Seguramente ninguno de mis clientes :-) * Creo que no necesitamos soporte RTL, ¿o sí? * – dom0

+0

Este es un post antiguo, así que probablemente mi no se responderá a la pregunta de comentario: ¿cómo crear un puntero de const a un puntero de const a una estructura de MySQL? – tchronis

58

En tales casos, el cdecl herramienta (o C++ decl) puede ser servicial:

 [[email protected] ~]$ cdecl explain "const struct s** ppMyStruct" 
    declare ppMyStruct as pointer to pointer to const struct s 
+1

Muy útil. ¿Por qué esta herramienta no es conocida? –

+0

¿Sabes por casualidad si está disponible para Windows? – Niklas

+0

Es de código abierto y afaik no tiene ningún requisito específico para el sistema operativo. Cuando tenga suerte debe poder compilarse con cualquier compilador, en el peor de los casos, debe usar las cosas de gcc/cygwin o mingw. – flolo

5

su colega está mal, y que es el mismo para C y C++. Pruebe lo siguiente:

typedef struct foo_t { 
    int i; 
} foo_t; 

int main() 
{ 
    foo_t f = {123}; 
    const foo_t *p = &f; 
    const foo_t **pp = &p; 
    printf("f.i = %d\n", (*pp)->i); 
    (*pp)->i = 888; // error 
    p->i = 999;  // error 
} 

Visual C++ 2008 da los siguientes errores para las dos últimas líneas:

error C2166: l-value specifies const object 
error C2166: l-value specifies const object 

GCC 4 dice:

error: assignment of read-only location '**pp' 
error: assignment of read-only location '*p' 

G ++ 4 dice:

error: assignment of data-member 'foo_t::i' in read-only structure 
error: assignment of data-member 'foo_t::i' in read-only structure 
+0

¿Por qué está esto downvoted? Solo pensé que era mejor dar un ejemplo específico, en lugar de simplemente decirle que él tiene razón. – csl

+0

Supongo que era un enemigo de Visual C++, amante de GNU C++ :-) – dmityugov

+1

No responde la pregunta – Dynite

18

Has acertado en tu interpretación. Aquí hay otra manera de verlo:

const MyStructure *  *ppMyStruct;  // ptr --> ptr --> const MyStructure 
     MyStructure *const *ppMyStruct;  // ptr --> const ptr --> MyStructure 
     MyStructure *  *const ppMyStruct; // const ptr --> ptr --> MyStructure 

Estas son todas las alternativas de un puntero puntero a uno con el calificador const. La regla de derecha a izquierda se puede usar para descifrar las declaraciones (al menos en C++; no soy experto en C).

+0

¿Qué hay de MyStructure const * * ppMyStruct ;? – tobi

+2

@tobi, eso es lo mismo que la primera línea. Ver http://stackoverflow.com/q/3694630/ (hablan de referencias, pero los punteros se comportan igual). – efotinis

3

Como corolario de los otros comentarios, no coloque 'const' primero. Realmente pertenece después del tipo. Eso habría aclarado el significado de inmediato, simplemente leyó RTL como de costumbre:

MyStructure const** ppMyStruct; 
+1

No veo cómo eso lo aclara, pero supongo que es una cuestión de hábito. Si el const es lo primero, me resulta igual de fácil leerlo RTL como "un puntero a un puntero a una MyStructure que es const". – Niklas

+0

cuando lo probé obtuve este cdecl> explicar estructura MyStructure const ** ppMyStruct; error de sintaxis ¿Alguien puede explicar por qué si esta es una forma correcta declaración C – prajul

0
void Foo(int  *  ptr, 
      int const *  ptrToConst, 
      int  * const constPtr, 
      int const * const constPtrToConst) 
{ 
    *ptr = 0; // OK: modifies the pointee 
    ptr = 0; // OK: modifies the pointer 

    *ptrToConst = 0; // Error! Cannot modify the pointee 
    ptrToConst = 0; // OK: modifies the pointer 

    *constPtr = 0; // OK: modifies the pointee 
    constPtr = 0; // Error! Cannot modify the pointer 

    *constPtrToConst = 0; // Error! Cannot modify the pointee 
    constPtrToConst = 0; // Error! Cannot modify the pointer 
} 
+0

No veo cómo esta es una respuesta a la pregunta. ¿Lo leíste mal? – Niklas