0

My understanding is that you put file guards in a file header1.h to make sure that for any source file source.c in your program, header1.h is included at most once in it.

However, everyone seems to strongly advise that header files should only contain function/variable declarations, and macros. Never function/variable definitions.

If we follow this practice, then there should be no problem of including header1.h multiple times in source.c, because you are allowed to declare variables/functions as many times as you want.

The only downside is that your code will be longer, but then is the only purpose of file guards to keep code short?

user56202
  • 299
  • 1
  • 9
  • 1
    "..because you are allowed to declare variables/functions as many times as you want." - Not quite. You can re-declare/re-define *some* things but not everything. – P.P Apr 14 '22 at 15:18
  • 3
    It can also have type definitions (structs/unions/typedefs). Also `static inline` functions are usually placed in headers – Eugene Sh. Apr 14 '22 at 15:19
  • 1
    not just to prevent recursion... which would be bad. But because [well.. multiple definitions is UB](https://stackoverflow.com/a/34986350) in C and a violation of the [One Definition Rule in C++](https://en.cppreference.com/w/cpp/language/definition) – Mgetz Apr 14 '22 at 15:19
  • Thanks. I know you can't have multiple definitions, but I thought header files are never supposed to contain definitions. I see from Eugene's comment that sometimes, they should. – user56202 Apr 14 '22 at 15:25
  • 1
    If two things are defined within _visible_ range of each other in C, depending on what they are, at the very least shadowing can occur causing unexpected behavior when one instance over-influences the other instance. More importantly multiply defined symbols can, and should be flagged as a compile time warning. Guards prevent multiple defines from occurring when a header file for example is included by more than one source – ryyker Apr 14 '22 at 15:25
  • 2
    @user56202 they can also be included recursively `A.h` includes `B.h` and `C.h` and vice versa. Include guards ensure they don't end up crashing the compiler. – Mgetz Apr 14 '22 at 15:27
  • 1
    Infinite loops like @Mgetz mentions would be very real if you took header guards out of the standard library for example. There are usually many inclusions of the other standard header files in there and without header guards the preprocessor would just never stop (until the recursion goes to deep). A->B->C->A->B->C->....-*boom* – Ted Lyngmo Apr 14 '22 at 15:40
  • Also, MSVC at least warns about multiple definitions of macros at warning level 4. So you would either need to disable that particular warning or have include guards anyway. – SoronelHaetir Apr 14 '22 at 15:46
  • 1
    Or consider what `` traditionally does: `int getc(FILE *); #define getc(f) ... `. That will fail rather badly if `` is included a second time. – Nate Eldredge Apr 14 '22 at 16:17
  • See [6.7.2.3 Tags constraints 1](https://port70.net/~nsz/c/c11/n1570.html#6.7.2.3p1): "A specific type shall have its content defined at most once." – Ian Abbott Apr 14 '22 at 19:03

0 Answers0