重新定义是否意味着我们正在尝试定义一个已经定义的实体。此问题出现在以下代码示例中:
int a=5;
int main()
{
int a=3;//redefinition? I think no, because `int a` denote an entity different from the global "a"
}
还有一个例子:
int foo(){ return 1; }
int main()
{
int foo();
int a=foo();//Now a is 1
}
我们不能在 main()
函数体中定义刚刚声明的 foo()
函数,但如果我们可以的话,它会是一个重定义吗?
局部变量可能会影响全局变量,这就是 ::
范围解析运算符的作用
#include <iostream>
using namespace std;
int a=5;
int main()
{
int a=3;
cout << a; // 3
cout << ::a; // 5
}
所以没有ODR问题在这里。
至于第二个例子,另一个函数中的函数声明(当它不被most-vexing-parse 混淆时),我推荐这个问题:Is there a use for function declarations inside functions?
并且:不,您不能重新定义您在 main() 中的函数。您可以重新声明它(即使使用不同的参数,从而声明一个新函数)但这并不意味着您可以这样定义它。
wiki page 中有一段精彩的摘录我推荐阅读:
In short, the ODR states that:
In any translation unit, a template, type, function, or object can
have no more than one definition. Some of these can have any number of
declarations. A definition provides an instance.
In the entire
program, an object or non-inline function cannot have more than one
definition; if an object or function is used, it must have exactly one
definition. You can declare an object or function that is never used,
in which case you don't have to provide a definition. In no event can
there be more than one definition.
Some things, like types, templates,
and extern inline functions, can be defined in more than one
translation unit. For a given entity, each definition must be the
same. Non-extern objects and functions in different translation units
are different entities, even if their names and types are the same.
Some violations of the ODR must be diagnosed by the compiler. Other
violations, particularly those that span translation units, are not
required to be diagnosed.1