Is there any situation where you wouldn't want

2019-02-16 23:43发布

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.

6条回答
等我变得足够好
2楼-- · 2019-02-16 23:55

Suppose you have a third party library, and you can't modify its code. Now suppose including files from this library generates compiler warnings. You would normally want to compile your own code at high warning levels, but doing so would generate a large set of warnings from using the library. You could write warning disabler/enabler headers that you could then wrap around the third party library, and they should be able to be included multiple times.

Another more sophisticated kind of use is Boost's Preprocessor iteration construct: http://www.boost.org/doc/libs/1_46_0/libs/preprocessor/doc/index.html

查看更多
劳资没心,怎么记你
3楼-- · 2019-02-16 23:57
<cassert>
<assert.h>

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

查看更多
做自己的国王
4楼-- · 2019-02-16 23:58

It can be a problem if you have two headers in a project which use the same include guard, e.g. if you have two third party libraries, and they both have a header which uses an include guard symbol such as __CONSTANTS_H__, then you won't be able to successfully #include both headers in a given compilation unit. A better solution is #pragma once, but some older compilers do not support this.

查看更多
该账号已被封号
5楼-- · 2019-02-17 00:05

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.

查看更多
你好瞎i
6楼-- · 2019-02-17 00:06

The problem with #pragma once, and the reason it is not part of the standard, is that it just doesn't always work everywhere. How does the compiler know if two files are the same file or not, if included from different paths?

Think about it, what happens if the compiler makes a mistake and fails to include a file that it should have included? What happens if it includes a file twice, that it shouldn't have? How would you fix that?

With include guards, the worst that can happen is that it takes a bit longer to compile.

Edit: Check out this thread on comp.std.c++ "#pragma once in ISO standard yet?"

http://groups.google.com/group/comp.std.c++/browse_thread/thread/c527240043c8df92

查看更多
Ridiculous、
7楼-- · 2019-02-17 00:10

@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.

查看更多
登录 后发表回答