Why not just declare structs in headers? Wouldn't this make include-guards unnecessary?

874 views Asked by At

I recently realized that while it is illegal to ever define something more than once in a given translation unit, it is perfectly legal to declare things (functions, variables, structs) as many times as you like. I was under the impression that the purpose of include guards was to prevent duplicate declarations.

In fact, their purpose seems to be to prevent duplicate definitions. However, since function and variable definitions properly belong in .c files and not .h files and only .h files are #include'd, this would seem to imply that only structs and unions present a problem (because we typically define them in .h files, not just declare them). (Even the example on the wikipedia page on include guards uses struct definitions).

My question is: why is it so common to define structs in header files? Couldn't we just declare them in header files and then put their definitions in .c files and then include guards would be completely unnecessary since duplicate declarations are okay?

If I had to guess, it's because if we did this, the only thing that source files that include such header files would be able to so is create pointers to the structs since the definition of what fields they contain is in some other .c file. Is that accurate?

2

There are 2 answers

1
AnT stands with Russia On BEST ANSWER

In order to meaningfully use a struct type, i.e in order to be able to access its contents, to define objects of that struct type, to know the size of that struct type you have to define that struct type. The definition has to be visible in every translation unit in which you want to use the struct type as mentioned above. This is the reason you'd want to define struct types in header files.

If you just declare struct types in header files, you won't be able to do any of that. The only thing you can do with declared (but not defined) struct type is declare pointers to that struct type. That is a valuable auxiliary feature, but by itself it is completely useless.

As an additional note, include guards are not just for preventing multiple definitions of struct types. C language also prohibits repetitive typedef declarations (C++ notably allows them), repetitive static function definitions, repetitive static variable definitions, repetitive macro definitions, repetitive enum definitions and probably something else as well.

But you are right, if your header file only contains declarations that can be legally repeated in the same translation unit, then formally you don't need include guards in that header file.

0
chux - Reinstate Monica On

OP:My question is: why is it so common to define structs in header files?

Structure that are used by multiple .c files need to share the same definition and so are in .h files.

Structures that are local to a single .c file (making them effectively "static" or of local scope) should be declared in the .c file and not in the paired .h file.

Include guards are needed in this context for maintenance. As OP says, the structure definition could be in .c files and shared that way (being the same), but that imposes a maintenance nightmare. Declare/define shared structures +once_ and then one can maintain them in one place.