-1

Based on the answer by sbi to this question,

An identifier can be declared as often as you want (statement 1)

But isn't it true that

an include guard in C++ just prevents the function declarations from showing up more than once in a single source file (statement 2)

?

My question is: why this contradiction? Or have I misunderstood either of the two statements?

Community
  • 1
  • 1
Nicholas
  • 2,560
  • 2
  • 31
  • 58
  • No. The include guard prevents a *header* from being included more than once. Depending on scoping, an identifier could be declared an infinite number of times across countless files or in a single file. – user4581301 Nov 29 '16 at 00:50
  • Class definition must be guarded – Danh Nov 29 '16 at 00:52
  • Rereading slightly, the scoping can even be ignored so long as the type of the identifier is unchanged because sbi is talking of declarations, not definitions. – user4581301 Nov 29 '16 at 00:54
  • 1
    Here is a simple example: http://ideone.com/hkS3Zc – user4581301 Nov 29 '16 at 00:56
  • @user4581301 Thanks for the example, at least, it's proven that statement 1 holds. But what on earth is ***a header being included more than once*** since after all the header's content is literally copied and pasted to the source file? – Nicholas Nov 29 '16 at 01:46
  • 1
    @Nicholas Think of how many headers have to `#include ` Would you want to process `class string { whole lotta code here };` over and over and over? Then think about all the templates and inlined functions that the compiler would have to weed through and ignore because they are identical. On top of that, what if some fool does define a variable in a header? Now you have potentially dozens of copies of the same variable and one really angry linker. – user4581301 Nov 29 '16 at 01:56

1 Answers1

4

Yes, you can declare (but not define) a function multiple times in a single translation unit. And yes, include guards usually prevent this, but that is not their only purpose. Headers often define classes, templates, and inline functions; the header guard is needed to prevent multiple definitions of those entities from appearing in a single translation unit. Header guards also help prevent an exponential blowup in the number of times a header gets pasted into a translation unit.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Are you suggesting that `include guard` essentially prevents duplicate definitions, not declarations, and only the former would trigger an error? I am still a bit confused. I am thinking like `#include " .h"` literally copy-and-pastes the content from the header file during the preprocessing, therefore the source file that has `#include " .h"` won't have any definition after preprocessing since we normally define the entity in a separate *cpp* file (and its declaration in a header), then how can the translation unit have multiple definitions of the entity? – Nicholas Nov 29 '16 at 01:40
  • @Nicholas The include guard prevents whatever it guards from appearing multiple times in a translation unit. That might include: non-inline function declarations, inline function definitions, class definitions, template definitions. And other kinds of declarations too, but those are the most important cases. – Brian Bi Nov 29 '16 at 01:52
  • "that is not their only purpose" -- right. But it's even stronger than that: if your headers contain **only** declarations then include guards aren't needed at all. It's all the other stuff that has to be guarded. – Pete Becker Nov 29 '16 at 13:49