error: los tipos en conflicto para ‘f’ y la statement anterior de ‘f’ estaban aquí

Este código es solo una situación que encontré en mi código real, que es muy grande, así que estoy dando esto. Aquí en este código, la estructura “estructura nodo” no está definida, está definida en otro archivo fuente c.

mi c código fuente:

/* test.c */ 1 #include 2 #include "test2.h" 3 4 void f(struct node * k) 5 { 6 7 } 

mi archivo de cabecera:

 /* test2.h */ 1 extern void f(struct node * k); 

Cuando compilo este código con gcc para crear un archivo de objeto:

 gcc -w -c test.c 

Yo obtengo:

 test.c:6: error: conflicting types for 'f' test2.h:1: error: previous declaration of 'f' was here 

He dado el prototipo completo de la función f() . ¿Por qué estoy recibiendo este error?

Otra cosa es que cuando no incluyo el archivo de cabecera test2.h en test.c y declaro explícitamente la función prototipo en test.c , se comstack correctamente. El código está abajo:

  /* test.c */ 1 #include 2 void f(struct node *k); 3 4 void f(struct node * k) 5 { 6 7 } 

gcc -c -w test.c

No hay error.

¿Podría explicar por qué esta vez no estoy recibiendo un error?

Esto no tiene nada que ver con la palabra clave extern en el prototipo (aunque no es necesario).

Necesita una statement de reenvío para el struct node :

 /* test2.h */ struct node; // <== this extern void f(struct node * k); 

Sin esa statement directa, el struct node dentro del prototipo de función es local a ese prototipo de función particular.

Entonces, cuando el comstackdor ve la definición de f() , también ve otra statement local diferente para un struct node y piensa que tiene una statement conflictiva para f() .

Ver C99 6.9.1 "Alcances de los identificadores":

Para cada entidad diferente que designa un identificador, el identificador es visible (es decir, se puede usar) solo dentro de una región del texto del progtwig llamada su scope. Las diferentes entidades designadas por el mismo identificador tienen diferentes ámbitos o están en espacios de nombres diferentes. Hay cuatro tipos de ámbitos: función, archivo, bloque y prototipo de función. (Un prototipo de función es una statement de una función que declara los tipos de sus parámetros).

...

Si el declarador o el especificador de tipo que declara el identificador aparece dentro de la lista de declaraciones de parámetros en un prototipo de función (que no forma parte de la definición de una función), el identificador tiene un scope de prototipo de función, que termina al final del declarador de función.

GCC 4.6.1 da una buena advertencia sobre esto para mí:

 C:\temp\test.c:3:22: warning: 'struct node' declared inside parameter list [enabled by default] C:\temp\test.c:3:22: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] 

C ++ hace que el scope del prototipo de función se aplique solo a los nombres de parámetros (C ++ 03 3.3.3), por lo que no verá este problema si comstack el código como C ++.

quitar el extern de la cabecera. Cuando declara una función como externa, guía al comstackdor de que la función no se va a comstackr, y cualquier referencia a esa función se resolverá en el enlace. Normalmente, esta statement se realiza cuando se trabaja con bibliotecas precomstackdas.

En su test2.h ha declarado f como extern , por eso está recibiendo el error. En test.c no hay statement extern en prototipo.