2

(My apology if this question sounds familiar, but I was really confused. And I could not comment under existing questions. )

I browsed a few questions, this, whose answer says:

If ...(defined a function in header), and then include the header into two or more different source files, you'll have multiple definitions of the same function.

But I thought the book taught us to always wrote definition guard inside headers. With the guard, we won't have multiple definitions, right?

I tried to find the reason in book , but with not much help: it says the reason (why function is declared in header file, and defined in source file) is the same reason as variables (in a previous chapter). And when I jump to that previous chapter, there is no explicit explanation.

Community
  • 1
  • 1
Minteh
  • 23
  • 3
  • 2
    For your interest see also [Coding C++ without headers, best practices?](http://stackoverflow.com/q/1001639/96780) and [What are the advantages and disadvantages of implementing classes in header files?](http://stackoverflow.com/q/1783849/96780). – Daniel Daranas Jul 16 '14 at 15:30
  • @DanielDaranas Good posts. Glad to see some alternative ways and why header is the way to go. – Minteh Jul 16 '14 at 16:14

5 Answers5

2

why declare a function in header but define it in source file?

The declaration is needed to call the function. It goes in the header so that any file which wants to call the function can include the header and have the declaration available.

There can only be one definition, so it goes in just one source file.

With the guard, we won't have multiple definitions, right?

There would be one definition in each source file that included the header. The guard prevents multiple inclusions from the same source file, but not inclusions from different source files.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Thanks for the answer. After reading the answers, I summarized that: multiple source files may be treated as different translation units. And in different translation units the guard will not help. – Minteh Jul 16 '14 at 16:09
  • Just curious, class definition is in headers (I just learn class today), does this mean there were multiple inclusions of a class definition? (which is not OK for function definition) – Minteh Jul 18 '14 at 02:47
  • @Minteh: You can only define a class once per translation unit (that's what the include guard is for); but it can, and often must, be defined in multiple units (which is why it's in a header). – Mike Seymour Jul 18 '14 at 10:54
2

But I thought the book taught us to always wrote definition guard inside headers.

Definition guard prevents a header to be included multiple times in one C file. It does not prevent a header from being included in multiple C files.

With the guard, we won't have multiple definitions, right?

If you put the definition in a header, and include that header in multiple C files, then you would end up with multiple definitions of the same function.

Having multiple definitions of a function or a variable will cause an error at linkage time, unless the function or the variable is static. In case of a static function / variable you would end up with multiple copies of that function / variable, which is not usually the desired outcome.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks for the answer. It seems I had some wrong thoughts about the compilation process of multiple source files. Now I have a better understanding. – Minteh Jul 16 '14 at 16:00
  • Just curious, class definition is in headers (I just learn class today), does this mean there were multiple inclusions of a class definition? (which is not OK for function definition) – Minteh Jul 18 '14 at 02:48
  • @Minteh No, compiler knows how to deal with multiple inclusion of class definition. – Sergey Kalinichenko Jul 18 '14 at 09:35
1

With the guard, we won't have multiple definitions, right?

Not right. Include guards ensure that when a source file is compiled, the header won't be processed twice. But when you have several source files, each file is compiled separately, so include guards do not stop multiple definitions.

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
  • Thanks for correcting my understanding of the compilation process. – Minteh Jul 16 '14 at 16:07
  • Just curious, class definition is in headers (I just learn class today), does this mean there were multiple inclusions of a class definition? (which is not OK for function definition) – Minteh Jul 18 '14 at 02:51
  • Yes. One-definition rule in C++ says that nothing can be defined twice in a translation unit (translation unit corresponds to a source file). For non-inline functions and variables the requirement is stronger - there may be only one definition in the whole program. – Wojtek Surowka Jul 18 '14 at 03:49
1

That's not the same thing, using a definition guard doesn't prevent one implementation from spanning multiple source files, it prevents the same declaration from being included more than once in the same file (which would cause compilation errors indeed).

So a guard is useless against a function defined directly in the header, since its implementation will be then included in multiple source files and, unless the compiler chooses to inline it, it will be present more than once. Placing the implementation in the source file will make the function being compiled in its own translation unit, and any call to it will be resolved accordingly.

Actually the compiler could inline even functions implemented in the source file so this could not happen.

Jack
  • 131,802
  • 30
  • 241
  • 343
  • Thanks for the answer. it explicitly answered the question in clear wording. – Minteh Jul 16 '14 at 15:58
  • Just curious, class definition is in headers (I just learn class today), does this mean there were multiple inclusions of a class definition? (which is not OK for function definition) – Minteh Jul 18 '14 at 02:49
1

A declaration goes in the header. A definition goes in the body. The header guard is to prevent multiple declarations at compile time, while compiling a single unit that may include the same header more than once (via other The definition goes in the body to prevent multiple compiled versions of the definition in multiple objects that included it colliding at link time.

Edit to answer comment because I can't format a comment:

It's not OK to define the same thing twice.

It is not OK to declare the same thing twice.

It is OK to pre-declare the same thing twice.

// predeclare:
class thingy;

// declare:
class thingy { int x(); };

// define:
thingy::x() { return 1; }

Anything you put in a header is likely to appear twice when compiling a single file because headers often get included by other headers, so they get included more than once. Header guards prevent this at compile time.

Anything you put in a header which defines something is likely to end up being defined in the compilation of more than one file if they both include the header, and then appear twice at link time. Header guards cannot prevent this, hence we avoid defining things in headers.

You can think of the #include in C++ as a giant macro - it means "grab an entire file and shove it into my source code at this point, before you compile it".

Andy Newman
  • 1,178
  • 2
  • 8
  • 23
  • Thanks for the answer. I wasn't aware that multiple source files may be treated as multiple translation units. – Minteh Jul 16 '14 at 16:06
  • Just curious, class definition is in headers (I just learn class today), does this mean there were multiple inclusions of a class definition? (which is not OK for function definition) – Minteh Jul 18 '14 at 02:51
  • I misread your comment ... that's an interesting point ... the class type is defined in the header and, amongst other things, will cause a vtable to exist... do we get 2 vtables? This is nolonger your original question and I won't answer here, just know that it is OK to have the class type defined in multiple object files at link time. – Andy Newman Jul 18 '14 at 12:52