Pregunta

he visto un montón de preguntas sobre esto, pero voy a hacer la pregunta de otra manera, no hay código específico. ¿Hay una manera de FÁCILMENTE para determinar qué está causando el tipo sea incompleta? En mi caso estoy usando el código de alguien más y estoy completamente seguro de que no tengo las cabeceras correctas, pero (ya que las computadoras hacen estas cosas mucho más rápido y mejor que los ojos humanos) es que hay una manera de conseguir el compilador decir "oye, piensa que tienen tipo X en la línea 34, pero que en realidad es faltante ". El error en sí mismo sólo aparece cuando se asigna, lo que no es muy útil.

¿Fue útil?

Solución

vi una pregunta el otro día en el que alguien utiliza inadvertidamente un tipo incompleto especificando algo así como

struct a {
    int q; 
}; 
struct A *x; 
x->q = 3;

El compilador sabía que era struct A una estructura, a pesar de estar totalmente A indefinido, en virtud de la palabra clave struct.

Eso fue en C ++, cuando tal uso de struct es atípicos (y, resulta, puede conducir a pies de tiro). En C si lo hace

typedef struct a {
    ...
} a;

A continuación, se puede utilizar a como el nombre de tipo y omitir el struct más tarde. Esto conducirá al compilador que le dará un error identificador no definido más adelante, en lugar de tipo incompleto, si escribe mal el nombre o se olvida de una cabecera.

Otros consejos

Otra posible razón es referencia indirecta. Si un código de referencias a una estructura que no se incluyen en el archivo actual c, el compilador se quejará.

  

A-> B-> C // error si b no se incluye en el archivo actual c

¿Qué quieres decir, el error sólo aparece cuando se asigna? Por ejemplo en GCC, sin asignación en vista:

int main() {
    struct blah *b = 0;
    *b; // this is line 6
}

incompletetype.c:6: error: dereferencing pointer to incomplete type.

El error es en la línea 6, que es donde solía un tipo incompleto como si fuera un tipo completo. Yo estaba bien hasta entonces.

El error es que se debería haber incluido cualquiera que sea cabecera define el tipo. Sin embargo, el compilador no puede adivinar línea de lo que debería haber sido incluido en: cualquier línea exterior de una función estaría bien, más o menos. Ninguno de los dos se va a ir a la pesca de arrastre a través de cada archivo de texto en su sistema, en busca de una cabecera que lo define, y sugieren que se debe incluir.

Como alternativa (punto bueno, potatoswatter), el error está en la línea en la que se definió b, cuando quería decir para especificar algún tipo que en realidad existe, pero en realidad blah especificado. Encontrar la definición de la variable b no debería ser demasiado difícil en la mayoría de los casos. IDE por lo general lo puede hacer por usted, tal vez las advertencias del compilador pueden no ser molestado. Es cierto código bastante atroz, sin embargo, si usted no puede encontrar las definiciones de las cosas que está utilizando.

No lo entiende exactamente cuál es el problema. tipo incompleto no es el tipo que está "perdido". Tipo Incompete es un tipo que es declarada pero no definido (en el caso de los tipos struct). Para encontrar la declaración no es fácil de definir. En cuanto a la búsqueda de la definición que falta ... el compilador no le ayuda aquí, ya que es la causa del error en el primer lugar.

Una razón importante de los errores de tipo C son incompletos en errores ortográficos en los nombres de tipos, que impiden el compilador de la concordancia de un nombre a la otra (como en la adecuación de la declaración de la definición). Pero, de nuevo, el compilador no le puede ayudar aquí. Compilador no hacen conjeturas sobre los errores tipográficos.

Este error normalmente indica si el nombre de su estructura es diferente de la inicialización de la estructura en el código, por lo que normalmente, c se encuentra el nombre de la estructura se pone y si no se encuentra la estructura original, esto haría normalmente aparece, o si apunta un puntero señalado en ese puntero, el error se mostrará.

A - Solución

En declaraciones para el lenguaje C, me acabo de encontrar ampirically que después de código de declaración será la solución;

typedef struct ListNode
{
    int data;
    ListNode * prev;
    ListNode * next;
} ListNode;

Así que, como regla general, que el mismo nombre para ambos, tanto para definición de tipo y el nombre de la estructura;

typedef struct X
{
    // code for additional types here
    X* prev; // reference to pointer
    X* next; // reference to pointer
} X;

B - Muestras Problemetic

Cuando siguientes declaraciones se consideran tanto incompleta por el compilador gcc al ejecutar siguiente declaración. ;

removed->next->prev = removed->prev;

Y consigo mismo error para el código de desreferencia informó en la salida de error;

>gcc Main.c LinkedList.c -o Main.exe -w
LinkedList.c: In function 'removeFromList':
LinkedList.c:166:18: error: dereferencing pointer to incomplete type 'struct ListNode'
     removed->next->prev = removed->prev;

Para ambos de la archivo de cabecera las declaraciones que figuran a continuación;

typedef struct
{
    int data;
    ListNode * prev;
    ListNode * next;
} ListNode;

Además éste;

typedef struct ListNodeType
{
    int data;
    ListNode * prev;
    ListNode * next;
} ListNode;

Fuera de posibles escenarios que implican la optimización de todo el programa, el código de código generado para algo como:

struct foo *bar;
struct foo *test(struct foo *whatever, int blah)
{
  return blah ? whatever: bar;
}

será totalmente afectado por lo que podría contener miembros struct foo. Debido utilidades le hacen generalmente recompilar cualquier unidad de compilación en la que la definición completa de una estructura aparece, incluso cuando tales cambios podría en realidad no afectará el código generado para ellos, es común omitir definiciones de estructuras completas de las unidades de compilación que en realidad no necesita ellos, y tal omisión en general, no es digno de una advertencia.

necesidades del compilador A tengan una estructura o unión definición completa para saber cómo manejar las declaraciones de los objetos del tipo con la duración, las declaraciones de los agregados que contienen los miembros de la clase, o código que tiene acceso a los miembros de la estructura o unión automática o estática. Si el compilador no tiene la información necesaria para realizar una de las operaciones anteriores, no tendrá más remedio que chillido al respecto.

Por cierto, hay una situación más que el nivel permitiría un compilador que requiere una definición completa unión para ser visible pero no requeriría un diagnóstico: si dos estructuras comienzan con una secuencia inicial común, y un tipo de unión que contiene tanto es visible cuando el compilador está procesando código que utiliza un puntero de uno de los tipos de estructura a inspecciona un miembro de esa secuencia inicial común, se requiere el compilador reconocer que tal código podría estar accediendo al miembro correspondiente de una estructura del otro tipo. No sé lo que los compiladores en su caso cumplir con la norma cuando el tipo de unión completa es visible, pero no cuando no es [gcc es propenso a generar código no conforme en cualquiera de los casos menos que se utilice la bandera -fno-strict-aliasing, en cuyo caso generará conforme código en ambos casos], pero si uno quiere escribir código que utiliza la regla de la CEI de una manera tal que garantice el comportamiento correcto en conformidad compiladores, uno puede necesitar para asegurar que completa la definición tipo de unión es visible; el no hacerlo puede resultar en un compilador que genera código de silencio falso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top