0

I have a file main.c, which contains the following line of code:

struct args packed;

the struct args is defined in another file named dct.c. However that file is not included. They are passed to the compiler as gcc -Wall main.c dct.c ...

Shouldn't the compiler emit a warning about an incomplete type?

Note that struct args is being instantiated and its members are accessed within main.c.

I only noticed this because of the linter warning me about an incomplete type, however GCC seems fine with it.

What am I missing? Because as I suspected, and according to this answer they are indeed different translation units and GCC can't see the definition in the second file.

Ait-Gacem Nabil
  • 165
  • 3
  • 12
  • 1
    The problem isn't plausible. GCC _will_ fail to compile the program under the circumstances you describe. However, just because `struct args` is defined in `dct.c` and even if it really isn't directly or indirectly included, doesn't mean that you can't (accidentally) have another definition for it somewhere else. `args` is a name that seems a likely candidate for naming conflicts with other headers/libraries. Please provide a [mre]. – user17732522 May 14 '23 at 10:47
  • If you had `struct args *packed;`, that would be legitimate even without a definition for the structure's content. You wouldn't be able to access the elements within the structure, but you could pass the pointer to functions that know how to do that (in the separate source file). – Jonathan Leffler May 14 '23 at 15:31

1 Answers1

2

Are you sure the struct isn't declared in a header file that your main.c includes? Are you using some IDE that is doing magic for you?

If I simply define a struct in one file and try to use it in the other it doesn't work as you describe:

gcc version 12.2.1 20230201 (GCC) 

$ gcc main.c args.c 
main.c: In function ‘main’:
main.c:5:15: error: storage size of ‘packed’ isn’t known
    5 |   struct args packed;
      |               ^~~~~~

This works:

$ cat args.h 
#ifndef _ARGS_H_
#define _ARGS_H_
struct args {
  int val;
};
#endif //_ARGS_H

$ cat args.c 
#include <stdlib.h>
#include "args.h"

struct args *makearg(int val) {
  struct args *ret = malloc(sizeof(struct args));
  ret->val = val;
  return ret;
}

$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include "args.h"

extern struct args *makearg(int val);

int main(int argc,char **argv) {
  struct args *packed = makearg(3);
  printf("%d\n",packed->val);
  free(packed);
  return 0;
}

$ gcc main.c args.c 
$ ./a.out 
3
Chase LP
  • 229
  • 2
  • 7