为什么编译器会允许这个?

时间:2013-12-28 12:22:34

标签: c++

以下编译成功:

struct XX {
  int element;
};

int main ()
{
  XX  XX, prev_XX  ;
  prev_XX = XX;
  XX = prev_XX;  //  ??? NO error: expected unqualified-id before '=' token
}

编译器如何知道它是类型还是变量?

修改:

这是一个错误:(来自sftrabbit的例子)

int main ()
{
    XX XX, prev_XX;
    XX XX2; // error: expected ';' before 'XX2'
}

4 个答案:

答案 0 :(得分:10)

变量名隐藏结构名称(§3.3.10):

  

可以通过嵌套声明性区域或派生类(10.2)中相同名称的显式声明来隐藏名称。

如果需要专门引用结构名称,则需要使用详细的类型说明符struct XX(§3.4.4):

  

精细类型说明符(7.1.6.3)可用于引用先前声明的类名或枚举名,即使该名称已被非类型声明隐藏(3.3.10)。 / p>

所以编译器知道XX引用了变量,因为它是可以对应的全部。它甚至不会考虑它引用结构的可能性。事实上,让我们看看如果我们尝试将其用作类型会发生什么:

struct XX {
    int elemnent;
};

int main ()
{
    XX XX, prev_XX;
    XX XX2; // Can we continue to use XX as a type?
}

我们确实收到错误:

error: expected ‘;’ before ‘XX2’

相反,我们必须执行struct XX XX2;,这不会出错。

答案 1 :(得分:1)

这是由于表达式的语法。

就像某些单词可以是名词或动词一样 - 取决于句子中的位置

答案 2 :(得分:1)

对象的名称隐藏了结构的名称。如果要指定结构,则应使用详细说明的名称,例如

XX XX;
struct XX YY;

它是在C ++中引入的,因为在C结构名称和变量名称属于不同的名称空间,因为在C中您必须始终使用结构指定关键字struct。在C ++中,允许使用不带关键字struct的结构名称,但是如果变量名称是硬币,则变量名称会隐藏结构名称。

答案 3 :(得分:1)

这是一个回顾C日的微妙问题。

当您声明XX XX;第二个XX(变量)阴影时,第一个XX(类型)。您仍然可以使用struct XX为其命名来访问该类型。

struct XX {};

int main() {
    XX XX;

    XX other; // error: expected ‘;’ before ‘other’

    struct XX another; // OK

    another = XX; // OK

    return 0;
}

您可以查看here