Reputation: 23
(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.
Upvotes: 2
Views: 571
Reputation: 1208
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".
Upvotes: 1
Reputation: 726559
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.
Upvotes: 2
Reputation: 133577
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.
Upvotes: 1
Reputation: 254461
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.
Upvotes: 2
Reputation: 20993
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.
Upvotes: 1