"redefinition"是什么意思?



重新定义是否意味着我们正在尝试定义一个已经定义的实体?这个问题出现在下面的代码示例中:

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问题。

至于第二个例子,函数声明在另一个函数内(当它不被最令人烦恼的解析混淆时),我建议这个问题:函数内的函数声明有什么用?

和:不,你不能在main()中重新定义函数。您可以重新声明它(即使使用不同的参数,从而声明一个新函数),但这并不意味着您可以这样定义

我推荐你阅读维基页面上的一段精彩摘录:

简而言之,ODR声明:

  • 在任何翻译单元中,模板、类型、函数或对象都可以定义不超过一个。其中一些可以有任意数量的声明。定义提供了一个实例。

  • 在整个程序中,对象或非内联函数不能有多个定义;如果使用对象或函数,则必须只有一个定义。你可以声明一个永远不会用到的对象或函数,在这种情况下,您不需要提供定义。无论如何也不能定义不止一个。

  • 有些东西,比如类型,模板,而外部内联函数,可以定义在一个以上翻译单元。对于给定的实体,每个定义必须是相同。不同翻译单位中的非外部对象和函数是不同的实体,即使它们的名称和类型相同。

某些违反ODR的行为必须由编译器诊断。其他违反,特别是那些跨越翻译单元的违反,则不是需要诊断。1

不,在处理重定义时,记住SCOPE是很重要的。它只适用于在同一作用域

中定义的具有相同名称的两个变量

在示例1中,第二个a是LOCAL SCOPE,并且是函数的局部。因此,这就是在退出函数体

之前查看和引用的a。

No。int a = foo();int a = 3;,在main()里面,是一个新的变量,也叫做a

重定义是试图重新定义相同的变量,例如:

int a = 5;
int a = 6;

int foo();

不是定义。这是一个宣言。函数定义包括{ }

重定义在某种程度上会导致编译时错误。例如:

int a;
bool a;

void f();
int f;

在你的例子中,没有编译时错误。它是关于名称隐藏,范围和解析规则。

int a = 5;
{
  int a = 6; //because of { } internal a is in other scope and can be defined without error
  int b = a; //b == 6
}
int b = a; //b == 5

在最后一种情况下,你有两个不同的"a",每个都在自己的程序范围内。在程序的某一点上,如果您使用"a"这样的名称,则在该名称后面只有一个实体。如果编译器不能在不同的变体之间找到"a"的最佳匹配,你会得到重新定义和错误。

第一个不是像你想的那样由于作用域不同而重新定义的

第二个是重新声明,但是你可以多次重新声明一些东西,尽管这个笑话会随着重复而变得陈旧。

如果你允许在函数内部定义函数,你就可以编写所有的语义,因为现在还没有这样的(除了lambda)。
对于这样做的人,请查看GCC C编译器,"嵌套函数"one_answers"语句表达式"。

无论如何,重新定义将是一个错误,由于一个定义规则。

相关内容

  • 没有找到相关文章

最新更新