“重新定义”是什么意思?

时间:2014-05-15 11:34:34

标签: c++ redefinition one-definition-rule

重新定义是否意味着我们正在尝试定义已定义的实体。此问题出现在以下代码示例中:

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
}

我们无法在foo()函数体内定义声明的main()函数,但是如果我们可以将其重新定义?

5 个答案:

答案 0 :(得分:3)

局部变量可能会影响全局变量,这是::范围解析运算符的用途

#include <iostream>
using namespace std;

int a=5;

int main()
{
    int a=3;

    cout << a; // 3
    cout << ::a; // 5
}

这里没有ODR问题。

至于第二个例子,另一个函数内部的函数声明(当它没有被最烦恼的解析弄糊涂时),我推荐这个问题:Is there a use for function declarations inside functions?

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

我推荐阅读wiki page的精彩摘录:

  

简而言之,ODR声明:

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

  •   
  • 整个   程序,对象或非内联函数不能有多个   定义;如果使用了一个对象或函数,它必须只有一个   定义。您可以声明一个从未使用过的对象或函数,   在这种情况下,您不必提供定义。在任何情况下都不能   有不止一个定义。

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

  •   
     

编译器必须诊断某些违反ODR的行为。其他   违规,特别是那些跨翻译单位的违规行为,不是   需要被诊断出来。1

答案 1 :(得分:0)

没有。 int a = foo();int a = 3;内的main()是一个新变量,也称为a

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

int a = 5;
int a = 6;

另外

int foo();

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

答案 2 :(得分:0)

不,在处理重新定义时,记住SCOPE非常重要。它仅适用于在SAME SCOPE中定义的两个具有相同名称的变量

在示例1中,第二个是LOCAL SCOPE并且是函数的本地。因此,在退出函数体

之前,这是查看和引用的a

答案 3 :(得分:0)

第一个不是由于不同的范围而重新定义,就像你想的那样。

第二个是重新声明,但你可以随意重新发布任何次数,但这个笑话会随着重复而变得陈旧。

如果允许在函数内部定义函数,则可以编写所有语义,因为还有这样的语言(除了lambdas)。
对于这样做的人,请查看GCC C编译器,&#34;嵌套函数&#34;和&#34;语句表达式&#34;。

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

答案 4 :(得分:0)

重新定义有点导致编译时错误。 例如:

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”的最佳匹配,则会得到重新定义和错误。

相关问题