rareza constante del puntero typedef

Resuelto Johannes asked hace 12 años • 6 respuestas

por favor considere el siguiente código:

typedef struct Person* PersonRef;
struct Person {
  int age;
};

const PersonRef person = NULL;

void changePerson(PersonRef newPerson) {
  person = newPerson;
}

Por alguna razón, el compilador se queja de que el valor de solo lectura no se puede asignar. Pero la constpalabra clave no debería hacer que el puntero sea constante. ¿Algunas ideas?

Johannes avatar Dec 14 '11 19:12 Johannes
Aceptado

Tenga en cuenta que

typedef int* intptr;
const intptr x;

no es lo mismo que:

const int* x;

intptres puntero a int. const intptres un puntero constante a int, no un puntero a constante int.

entonces, después de un puntero typedef, ¿ya no puedo hacerlo constante con el contenido?

Hay algunas formas feas, como la macro typeof de gcc :

typedef int* intptr;
intptr dummy;
const typeof(*dummy) *x;

pero, como ves, no tiene sentido si conoces el tipo que hay detrás intptr.

Piotr Praszmo avatar Dec 14 '2011 12:12 Piotr Praszmo
const PersonRef person = NULL;

es

struct Person*const person= NULL;

entonces estás contrastando el puntero y no el objeto.

Jens Gustedt avatar Dec 14 '2011 12:12 Jens Gustedt

Si bien el problema ya está resuelto con las respuestas anteriores, olvido la razón por la cual...

Entonces, tal vez como regla general:

  1. Siempre constse refiere a su token predecesor.
  2. En caso de que no exista tal, es "constante" su token sucesor.

Esta regla realmente puede ayudarle a declarar un puntero a punteros constantes o algo igualmente interesante.

De todos modos, con esto en mente, debería quedar claro por qué

struct Person *const person = NULL;

declara un puntero constante a una estructura mutable.

Piénselo, su typedef "agrupa" el struct Persontoken con el puntero *. Entonces, para escribir

const PersonRef person = NULL;

su compilador ve algo como esto (pseudocódigo):

const [struct Person *]person = NULL;

Como no queda nada const, declara constante el token a su derecha struct Person *.

Bueno, creo que esta es la razón por la que no me gusta ocultar punteros mediante typedefs, mientras que sí me gustan los typedefs como tales. ¿Qué pasa con la escritura?

typedef struct Person { ... } Person;
const Person *person; /*< const person */
Person *const pointer; /*< const pointer to mutable person */

y debería quedar bastante claro para los compiladores y los humanos lo que estás haciendo.

Zappotek avatar Dec 14 '2011 13:12 Zappotek