Why does C99 complain about storage sizes?

c99, gcc, gnu99, linux, network-programming

Solution

It's a chain of consequences of preprocessing and GNU C vs C99.

First up, `net/if.h`:

- `net/if.h` includes `features.h`

- Later on, it defines `struct ifreq` inside a `#ifdef __USE_MISC` block.

So:

- What is `__USE_MISC`? -- it is stuff common to BSD and System V

- Is it defined at this point? -- We need to check that out in `features.h`

So now, `features.h`:

- When you use `--std=c99` GCC by default defines `__STRICT_ANSI__` (since thats what C99 is)

- While preprocessing `features.h`, when `__STRICT_ANSI__` is on, the BSD and System V features don't kick in. i.e. `__USE_MISC` is left undefined.

Back up to `net/if.h`: `struct ifreq` does not even exist after preprocessing! Therefore, the complaint about storage size.

You can catch the whole story by doing:

vimdiff <(cpp test.c --std=c99 -dD) <(cpp test.c --std=gnu99 -dD)

or diff'ing them in any other way (like `diff --side-by-side`) instead of `vimdiff`.

If you want this to cleanly compile with `-std=c99`, you must consider the inclusion of the `_DEFAULT_SOURCE` feature test macro (for glibc versions >= 2.19; for older glibc versions, use either `_BSD_SOURCE` or `_SVID_SOURCE`) so that the required functionality is enabled on top of what is offered by C99.

Problem

This is some code I'm compiling on Linux: ``` #include <net/if.h> int main() { struct ifreq ifr; } ``` `gcc test.c` is fine. `gcc -std=gnu99 test.c` is fine. `gcc -std=c99 test.c` fails with the following error: ``` test.c: In function ‘main’: test.c:4:16: error: storage size of ‘ifr’ isn’t known ``` What's different about C99 that it doesn't like the definition of `struct ifreq` in Linux?

Original source

Related problems