简体   繁体   中英

How does the scope of structures, unions, etc work when functions are involved?

I recently came across structures and some things aren't quite clear. Let's say that I've got a program like this:

struct num print_a(struct num c); 

int main(){
  struct num{
    int a;
    int b;
  }c = {1, 2};
  struct num d;
  d = print_a(c);
}

struct num print_a(struct num c){
  printf("%d", c.a);
  return c;
}

Would this work or do I have to declare struct num outside of main? Because how can my function print_a "see" what struct num means (the type that it has to return) as it's declared outside of its scope?

Sorry if the question is dumb

Would this work or do I have to declare struct num outside of main?

Well, why not simply try it out?

http://ideone.com gives:

Compilation error #stdin compilation error #stdout 0s 9424KB
prog.c: In function ‘main’:
prog.c:11:15: error: type of formal parameter 1 is incomplete
   d = print_a(c);
               ^
prog.c:11:3: error: invalid use of undefined type ‘struct num’
   d = print_a(c);
   ^
prog.c:10:14: warning: variable ‘d’ set but not used [-Wunused-but-set-variable]
   struct num d;
              ^
prog.c: At top level:
prog.c:14:31: error: parameter 1 (‘c’) has incomplete type
 struct num print_a(struct num c){
                               ^
prog.c:14:12: error: return type is an incomplete type
 struct num print_a(struct num c){
            ^~~~~~~
prog.c:14:12: error: conflicting types for ‘print_a’
prog.c:3:12: note: previous declaration of ‘print_a’ was here
 struct num print_a(struct num c);
            ^~~~~~~
prog.c: In function ‘print_a’:
prog.c:16:10: warning: ‘return’ with a value, in function returning void
   return c;
          ^
prog.c:14:12: note: declared here
 struct num print_a(struct num c){
            ^~~~~~~

http://coliru.stacked-crooked.com/ gives:

main.cpp: In function 'main':
main.cpp:13:15: error: type of formal parameter 1 is incomplete
   d = print_a(c);
               ^
main.cpp:13:7: error: invalid use of undefined type 'struct num'
   d = print_a(c);
       ^~~~~~~
main.cpp:12:14: warning: variable 'd' set but not used [-Wunused-but-set-variable]
   struct num d;
              ^
main.cpp: At top level:
main.cpp:16:31: error: parameter 1 ('c') has incomplete type
 struct num print_a(struct num c){
                    ~~~~~~~~~~~^
main.cpp:16:12: error: return type is an incomplete type
 struct num print_a(struct num c){
            ^~~~~~~
main.cpp:16:12: error: conflicting types for 'print_a'
main.cpp:5:12: note: previous declaration of 'print_a' was here
 struct num print_a(struct num c);
            ^~~~~~~
main.cpp: In function 'print_a':
main.cpp:18:10: warning: 'return' with a value, in function returning void
   return c;
          ^
main.cpp:16:12: note: declared here
 struct num print_a(struct num c){
            ^~~~~~~

Hmmm... kind of give us the answer: no - it will not work

When you define the struct inside main, it is only known inside main. If you want to use the struct outside main you have to move the definition of the struct out of main - like:

struct num {
    int a;
    int b;
};

struct num print_a(struct num c); 

int main(){
  struct num c = {1, 2};
  struct num d;
  d = print_a(c);
}

struct num print_a(struct num c){
  printf("%d", c.a);
  return c;
}
  1. The declaration

     struct num print_a(struct num c); 

    at the beginning of the example code tells the compiler that:

    • You promise to define a struct num at file scope. For the moment, the compiler labels struct num as an incomplete type , which can be used in (some) declarations, for example, to declare (but not to define ) functions, and to declare or define pointer types and variables. The compiler won't hold you to this promise unless you actually try to use the type struct num .

      You must complete the definition of struct num before using that type in a definition or in a declaration where its size matters.

    • You promise to define a function named print_a taking a struct num and returning a struct num . The compiler won't hold you to this promise unless you actually try to use this function -- if you don't actually call it anywhere in the program, the compiler will forgive an unfulfilled promise.

  2. The struct num defined inside the function main has nothing to do with the incomplete struct num at file scope. You are of couse allowed to go ahead and define it, but it will shadow the file-level struct num .

  3. The statement

     d = print_a(c); 

    inside function main is incorrect, and will cause the compiler to generate several error messages, because it breaks the promises you made. Specifically, the compiler will complain that you are trying to use the incomplete type struct num declared at file scope as if it were complete. Remember that the struct num defined inside main has nothing to do with the struct num at file level.

  4. The function definition

     struct num print_a(struct num c){ ... } 

    is incorrect, because you have not kept your promise to define the type struct num . That inside main there is another type named struct num doesn't count; that type is usable only inside main .

To correct the program you need to move the definition of struct num before main . It can come before or after the declaration of print_a .

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