2011-05-13 20 views
6

tengo esta en un archivo C:"parámetro tiene tipo incompleto" advertencia

struct T 
{ 
    int foo; 
}; 

el archivo C tiene un incluir a un archivo h con esas líneas:

typedef struct T T; 
void listInsertFirst(T data, int key, LinkedList* ListToInsertTo); 

la función listInsertFirst es en el que estoy recibiendo la advertencia. ¿Cómo puedo arreglarlo?

+0

gracias, y ¿qué pasa si quiero que se escriba el tipo si alguien incluye el archivo h? – Belgi

+0

¿Cómo se define LinkedList? –

+2

Una cosa que debes tener en cuenta es que estás pasando una 'struct' * por valor * aquí. Eso es casi seguro que es una mala idea ... –

Respuesta

2

Como hemos descubierto en los comentarios, el problema fue que la definición de struct T ocurrió después de la definición de T en el encabezado. Realmente tienes cosas al revés aquí. El encabezado debe definir todos los tipos y prototipos de función y sus archivos C deberían estar usándolos.

Lo que quiere hacer en su lugar es cambiar la firma de su función de inserción para recibir un puntero a sus datos y el tamaño de los datos. Luego puede asignar memoria para los datos, copiarlos y almacenarlos. No necesita un tipo específico, simplemente declare que es void *.

void listInsertFirst(void *data, size_t data_size, int key, LinkedList* ListToInsertTo); 

Entonces la persona que llama haría algo como esto:

struct T { int foo; }; 
struct T x = { ... }; 
int someKey = ...; 
LinkedList *someList = ...; 
listInsertFirst(&x, sizeof x, someKey, someList); 
0

¿Está seguro de que es el primer parámetro que es el problema? Para estar seguro, intente cambiar temporalmente el tipo de parámetro de T a int. Lo más probable es que el tercer parámetro sea realmente el problema.

Muchos compiladores no señalan el problema en este tipo de problemas muy bien.

0

Intente mover la definición de la estructura al archivo h, antes del typedef.

+0

el problema con esto es que tengo: typedef struct LinkedList { \t ListNode * head; \t ListNode * tail; } LinkedList; que usa el tipo "ListNode", Si pongo esta estructura typedef en el archivo h, tendría que agregar la estructura typedef de "ListNode", pero nadie debería estar al tanto de este tipo ... – Belgi

+0

Pero LinkedList debe estar al tanto de ListNode. Por lo tanto, si alguien conoce LinkedList, también debe tener en cuenta ListNOde. También puede agregar otro archivo h: Agregar ListNode al nuevo archivo h e incluirlo en su archivo h original – Amir

+0

Amir, que es una buena idea. Gracias. – Belgi

2

Cuando incluye el archivo de encabezado, el compilador sabe que T es una estructura de tamaño desconocido y que listInsertFirst quiere uno como primer argumento. Pero el compilador no puede organizar una llamada al listInsertFirst ya que no sabe cuántos bytes presionar en la pila para el parámetro T data, el tamaño de T solo se conoce dentro del archivo donde se define listInsertFirst.

La mejor solución sería cambiar listInsertFirst tomar un T* como primer argumento por lo que diría tu archivo de cabecera esto:

extern void listInsertFirst(T *data, int key, LinkedList* ListToInsertTo); 

A continuación, se obtiene un puntero opaco para su tipo de datos T y, puesto que todos los punteros son del mismo tamaño (al menos en el mundo moderno), el compilador sabrá cómo construir la pila al llamar al listInsertFirst.

0
  1. Definir struct T en la cabecera, no en el archivo .c;
  2. Elija diferentes nombres para structure y typedef.
Cuestiones relacionadas