简体   繁体   中英

Order of declaration does not matter for a struct?

#include <stdio.h>
#include <stdlib.h>
void f(struct emp);
struct emp{
char name[20];
int age;
};
int main(){
    struct emp  e = {"nikunj", 23}  ;
    f(e);
    return 0;
}

void f(struct emp e){
    printf("%s %d\n", e.name, e.age);
}

Running the above code gives the following errors

nikunjbanka@ubuntu:~$ gcc hello2.c -o main.out
hello2.c:3:15: warning: ‘struct emp’ declared inside parameter list [enabled by default]
hello2.c:3:15: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
hello2.c: In function ‘main’:
hello2.c:10:2: error: type of formal parameter 1 is incomplete
hello2.c: At top level:
hello2.c:14:6: error: conflicting types for ‘f’
hello2.c:3:6: note: previous declaration of ‘f’ was here

But the book test your C skills says that the order of prototype declaration and structure declaration in the program does not matter. I want to ask whether the order matters or not?

Yes the order absolutely does matter.

Re-order your code such that the definition of struct emp appears before the function prototype for f .

#include <stdio.h>
#include <stdlib.h>

struct emp{
  char name[20];
  int age;
};

void f(struct emp);

...

gcc is actually trying to tell you that you did things in the wrong order, however the compiler messages are a little bit confusing if this is your first time reading through them.

These two warnings:

hello2.c:3:15: warning: ‘struct emp’ declared inside parameter list [enabled by default]
hello2.c:3:15: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]

indicate that the type of 'struct emp' was not known at the time gcc compiled line 3 of your file. The compiler will typically try to infer a default type & size for the unknown struct emp and almost always guesses incorrectly because it has no idea how you will eventually declare struct emp .

This error:

hello2.c:10:2: error: type of formal parameter 1 is incomplete

indicates that you are trying to call function 'f' with an actual parameter type that is different than the formal parameter type that gcc (incorrectly) inferred when it compiled line 3 of the file.

This error and associated note:

hello2.c:14:6: error: conflicting types for ‘f’
hello2.c:3:6: note: previous declaration of ‘f’ was here

indicates that the formal parameter type on line 14 (which is now known to be the type struct emp you declared on lines 4 through 7) did not match the formal parameter type that gcc (again incorrectly) inferred on line 3.

Bottom line: define all of your types before the prototypes that refer to them, and you should be fine.

You may also find your code is more readable if you use

typedef struct {
   char name[20];
   int  age;
} emp_t;

And then you can use emp_t rather than struct emp throughout the subsequent code.

There's another option - this change will fix it too:

#include <stdio.h>
#include <stdlib.h>
 struct emp;   /* <--- add this line */

void f(struct emp); /* <-- now this refers to that */
struct emp{        /* <-- and this defines the same thing */
char name[20];     /* and you didn't need to move things around. */
int age;
};

In a complex project it's not always easy to resolve all the ordering issues, this can be helpful.

Note that when f is actually f(struct emp*) --not f(struct emp)- then you may be able to define f() without including a definition of the struct layout. This is because the compiler can work with pointers to structs that are named, but not defined - provided you only do certain things to them (store them, return them, pass them to other functions; compare them to NULL, or to other pointers to the same thing... cast them to other pointer types...) - but you can't do pointer arithmetic, or access members (obviously) or ask for sizeof(*p) if p is a pointer to an unspecified struct. The compiler will let you know :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM