2011-02-07 13 views
5

En Objective-C ID es un typedef:Objetivo-C; typedef objc_object como sustituto de id sin puntero;

typedef struct objc_object { 
    Class isa; 
} *id; 

Así que puede declarar (e inicializar) un ejemplo variable de como este:

// using id 
id po_one = @"one"; 

Compilar bien.

Desde que el nombre de mi tipos en un esquema propio y ya que me gusta el puntero implícita en el ello typedef Quiero añadir una propia typedef (con O para objeto) como esto:

typedef struct objc_object O; 

Así una variable Declaración (con inicialización) podría verse como:

// using O 
O * po_two = @"two"; 

Esto compila con una advertencia:

inicialización de i puntero ncompatible tipo

Por lo que yo entiendo typedefs pensé que este último debe ser equivalente a:

// using struct objc_object 
struct objc_object * po_three = @"three"; 

que de nuevo compila bien.

Es asombroso que:

po_two = po_one; 
po_two = po_three; 

tanto compilar sin advertencias.

así que he intentado:

typedef struct objc_object * PO; 

para ver si funciona sin previo aviso si incluyo el puntero (siendo exactamente lo que quiero evitar - por lo que sólo por razones de prueba) para ver si un typedef fuera del la definición de estructura funciona de manera diferente a un typedef en la definición de estructura (que es la definición de id en este caso).

// using PO 
PO po_four = @"four"; 

Eso también funciona bien.

Si uso:

#define O struct objc_object 

el constructo utilizando O compila de nuevo sin advertencia.

Pero prefiero usar typedefs en lugar de a define siempre que sea posible.

Estoy perplejo. ¿Cuál es mi malentendido con typedefs?

+0

¿Qué compilador? – JeremyP

+1

Además, podría usar 'NSObject *' en lugar de 'O *', p. Ej. 'NSObject * po_two = @" two ";', en la mayoría de los casos. –

Respuesta

2

No soy un experto en compiladores, por lo que probablemente un verdadero experto pueda darle una mejor respuesta. En cualquier caso, según mi conocimiento, cuando un compilador realiza una comprobación de tipo, basa esta comprobación en el "árbol de análisis sintáctico", que genera un tipo de tabla para todas las posibles estructuras de tipo de datos y verifica si dos definiciones apuntan a la misma fila en la mesa. Por lo tanto, funciona buscando símbolos y escribiendo definiciones de esta tabla y comparándolas. Ahora "struct objc_object" es una de estas estructuras de datos.Luego, cuando se define id, genera otra entrada: "id -> struct objc_object *". La definición de po_three lleva a la misma referencia: "struct objc_object *" (infact "=" tiene la precedencia más baja). Lo mismo ocurre con po_four, porque PO lidera por definición a la misma referencia, nuevamente (PO -> struct objc_object *). Cuando usa la definición con #define, gracias al preprocesamiento todavía hace referencia a "struct objc_object *". Pero cuando usa

O * po_two = @"two"
, de hecho está tratando de hacer coincidir un tipo que es "id" (@ "dos"), es decir "struct objc_object *" y otro que es un puntero a "struct objc_object" pero incluso si lógicamente son lo mismo, no conducen a la misma referencia en la tabla. La razón es porque todavía se ha definido el tipo "O", por lo que po_two simplemente se almacena en la tabla de símbolos como un puntero a "O" y "O -> struct objc_object". Y esa es la razón de la advertencia: po_two es un puntero a algo diferente a @ "dos".

Tengo una curiosidad: ¿ha intentado trazar la tabla de símbolos con "nm"?

+0

Podría ser una buena suposición con entradas de tabla no coincidentes. Intenté nm pero no proporciona información útil. También el depurador solo muestra los mismos tipos, al menos después de la inicialización. Mi pequeña conjetura en este momento es que hay un truco incorporado en gcc que habilita cualquier puntero para convertir a id. Pero tal vez simplemente se olvidó de considerar reglas normales de tipo c (que deberían conducir a tipos equivalentes para id y O *) y, por lo tanto, el typedef produce la advertencia. – carpetemporem

+0

Sí, y esto podría explicar la advertencia faltante en po_two = po_three. – viggio24

Cuestiones relacionadas