Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any situation where you wouldn't want include guards?

I know why include guards exist, and that #pragma once is not standard and thus not supported by all compilers etc.

My question is of a different kind:

Is there any sensible reason to ever not have them? I've yet to come across a situation where theoretically, there would be any benefit of not providing include guards in a file that is meant to be included somewhere else. Does anyone have an example where there is an actual benefit of not having them?

The reason I ask - to me they seem pretty redundant, as you always use them, and that the behaviour of #pragma once could as well just be automatically applied to literally everything.

like image 680
Mephane Avatar asked Mar 04 '11 08:03

Mephane


3 Answers

I've seen headers that generate code depending on macros defined before their inclusion. In this case it's sometimes wanted to define those macros to one (set of) value(s), include the header, redefine the macros, and include again.
Everybody who sees such agrees that it's ugly and best avoided, but sometimes (like if the code in said headers is generated by some other means) it's the lesser evil to do that.

Other than that, I can't think of a reason.

like image 107
sbi Avatar answered Oct 21 '22 17:10

sbi


@sbi already talked about code generation, so let me give an example.

Say that you have an enumeration of a lot of items, and that you would like to generate a bunch of functions for each of its elements...

One solution is to use this multiple inclusion trick.

// myenumeration.td
MY_ENUMERATION_META_FUNCTION(Item1)
MY_ENUMERATION_META_FUNCTION(Item2)
MY_ENUMERATION_META_FUNCTION(Item3)
MY_ENUMERATION_META_FUNCTION(Item4)
MY_ENUMERATION_META_FUNCTION(Item5)

Then people just use it like so:

#define MY_ENUMERATION_META_FUNCTION(Item_) \
  case Item_: return #Item_;

char const* print(MyEnum i)
{
  switch(i) {
    #include "myenumeration.td"
  }

  __unreachable__("print");
  return 0; // to shut up gcc
}

#undef MY_ENUMERATION_META_FUNCTION

Whether this is nice or hackish is up to you, but clearly it is useful not to have to crawl through all the utilities functions each time a new value is added to the enum.

like image 6
Matthieu M. Avatar answered Oct 21 '22 17:10

Matthieu M.


<cassert>
<assert.h>

"The assert macro is redefined according to the current state of NDEBUG each time that <assert.h> is included."

like image 4
Windows programmer Avatar answered Oct 21 '22 18:10

Windows programmer