问题
I have read materials below:
https://www.wikiwand.com/en/One_Definition_Rule
http://en.cppreference.com/w/cpp/language/definition
What is the difference between a definition and a declaration?
But still, can't figure out why it is One Definition Rule rather than One Declaration Rule?
I maintain that declaration is a subset of definition, so One Definition Rule is enough.
回答1:
Definition is a subset of declaration, not the other way around. Every definition is a declaration, and there are declarations that are not definitions.
int i = 3; // definition and declaration
extern int i; // ok: (re)declaration
int i = 4; // error: redefinition
extern int j; // declaration
extern int j; // ok: (re)declaration
int j = 5; // ok: (re)declaration and definition
int j = 6; // error: redefinition
回答2:
One declaration rule would be too strict, preventing programs that use the same header more than once from compiling. It would also make it impossible to define data structures with back references.
A simple way to see the first point (using headers) is to consider a program composed of two translation units, A.cpp
and B.cpp
, which both include <string>
header.
Translation units A.cpp
and B.cpp
are translated independently. By including <string>
, both translation units acquire a declaration of std::string
.
As for the second point (data structures with back references) consider an example of defining a tree in which each node has a back reference to its parent tree:
// Does not compile
struct tree {
struct node *root;
};
struct node {
struct node *left;
struct node *right;
struct tree *owner;
};
This example would not compile, because node
from struct node *tree
is undeclared. Switching the order of struct node
and struct tree
declarations wouldn't help, because then tree
from struct tree *owner
would be undeclared. The only solution in C and C++ is to introduce a second declaration for either of the two struct
s.
回答3:
Because the same declaration, in a .h file, may be included in multiple compilation units, and because multiple definitions is definitely a programming error, whereas multiple declarations isn't.
回答4:
Because when you have declared a function in a header file
// header toto.h
int f(void);
and you want to define it in the compilation unit where it belongs, you'd do
#include "toto.h"
int f(void) {
return 0;
}
The definition is also a declaration, so this compilation unit sees two declarations, one in the header and one in the .c
or .cpp
file.
In short, the multiple declaration rule allows to check for consistency between different source files.
回答5:
The reason is really that the C++ translation model can easily deal with conflicting multiple declarations; it just requires the compiler part of the toolset to detect errors like this in the source code:
int X();
void X(); // error
A compiler can easily do that.
And when there are no such errors in any translation units, then there's no problem; every X()
call in every translation unit is identical; what remains to do is for the linker to link every call to the one correct destination. The declarations have done their job and no longer play a role.
Now with multiple definitions, it's not that easy. Definitions are something which concerns multiple translation units and which goes beyond the scope of the compilation phase.
We've already seen that in the example above. The X()
calls are in place, but now we need the guarantee that they all end up at the same destination, the same definition of X()
.
That there can be only one such definition should be clear, but how to enforce it? Put in simple terms, when it's time to link the object code together, the source code has already been dealt with.
The answer is that C++ basically chooses to put the burden on the programmer. Forcing compiler/linker implementors to check all multiple definitions for equality and detect differences would be beyond the capabilities of C++ toolsets in most real-life situations or completely break the way those tools work, so the pragmatic solution is to just forbid it and/or force the programmer to make sure that they are all identical or else get undefined behaviour.
来源:https://stackoverflow.com/questions/46988095/why-one-definition-rule-not-one-declaration-rule