priyaranjan
priyaranjan

Reputation: 379

error: conflicting types for 'f' and previous declaration of 'f' was here

This code is just a situation that I found in my actual code which is very big so I'm giving this.here in this code the structure "struct node" is not defined it is defined in another c source file.

my c source code:

/* test.c */

  1 #include<stdio.h>
  2 #include "test2.h"
  3
  4 void f(struct node * k)
  5 {
  6   
  7 }

my header file :

/* test2.h */

  1 extern void f(struct node * k);

When I compile this code with gcc to create an object file:

gcc -w -c test.c

I get:

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

I have given the complete prototype of function f(). Why I am getting this error?

Another thing is that when I don't include the header file test2.h in test.c and explicitly declare the function prototype in test.c, it compiles successfully. Code is below:

 /* test.c */

      1 #include<stdio.h>
      2 void f(struct node *k);
      3
      4 void f(struct node * k)
      5 {
      6
      7 }

gcc -c -w test.c

No error.

Can you please explain why this time I am not getting an error?

Upvotes: 3

Views: 9029

Answers (3)

Michael Burr
Michael Burr

Reputation: 340198

This has nothing to do with the extern keyword on the prototype (although it's not necessary).

You need a forward declaration for struct node:

/* test2.h */

struct node;  // <== this

extern void f(struct node * k);

Without that forward declaration, the struct node inside the function prototype is local to that particular function prototype.

So when the compiler sees the definition of f() it also sees another different local declaration for a struct node and thinks that you have a conflicting declaration for f().

See C99 6.9.1 "Scopes of identifiers":

For each different entity that an identifier designates, the identifier is visible (i.e., can be used) only within a region of program text called its scope. Different entities designated by the same identifier either have different scopes, or are in different name spaces. There are four kinds of scopes: function, file, block, and function prototype. (A function prototype is a declaration of a function that declares the types of its parameters.)

...

If the declarator or type specifier that declares the identifier appears within the list of parameter declarations in a function prototype (not part of a function definition), the identifier has function prototype scope, which terminates at the end of the function declarator.

GCC 4.6.1 gives a nice warning about this for me:

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++ makes function prototype scope apply only to the parameter names (C++03 3.3.3), so you won't see this problem if you compile the code as C++.

Upvotes: 7

stdcall
stdcall

Reputation: 28880

remove the extern from the header. When you declare a function as external, you guide the compiler that the function is not going to be compiled, and any reference to that function will be resolved in the linkage. Usually, this declaration is done when working with pre compiled libraries.

Upvotes: 2

taskinoor
taskinoor

Reputation: 46027

In your test2.h you have declared f as extern, that's why you are getting the error. In test.c there is no extern declaration in prototype.

Upvotes: 1

Related Questions