声明中类型和对象的相同标识符

same identifier for type and object in declaration

本文关键字:标识符 对象 类型 声明      更新时间:2023-10-16

我偶然发现了一个函数实现,该函数实现回收了相同类型的参数的类型名称。代码编译并且似乎完全符合预期。这是一个最小化版本:

#include <iostream>
using namespace std;
struct X {
int v;
};
void print_X(const X& X)   // <--- here the identifier X has *two different meanings*
{
cout << "X.v:" << X.v << endl;
}

该代码是针对 Borland C++ 5.6.4 开发的

我尝试了几种不同且更新的编译器:

  • C++11(mingw32-g++ 4.9.2,随 CodeBlocks 16.01 一起提供(
  • C++(GCC 6.3(
  • C++14 (GCC 6.3(
  • C++ 4.3.2 (GCC 4.3.2(
  • C++14 (叮当 4.0(

所有人都毫无怨言地接受它。

我不认为这C++很好,但是...

它C++有效吗?如果是,将来是否有效?

更新

多么恐怖!直到现在我才明白,一个简单的变量声明也是如此:

X X;

演示:http://ideone.com/a9GM49

更新 #2

C++与 C 语言共享此功能:

#include <stdio.h>
typedef struct X {
int v;
} X;
int main()
{
X X;
X.v = 7;
printf("X.v:%dn", X.v);
return 0;
}

演示:http://ideone.com/nheZTa

是的,它是有效的。您正在内部作用域中声明一个变量(参数(,该变量(参数(在外部作用域中隐藏了该名称。

在这种情况下,当然不是一个好主意。

它是有效的。它从外部作用域中隐藏变量。像这样隐藏通常称为阴影,您的编译器可能有一个警告,您可以启用警告以告诉您何时发生(gcc 有-Wshadow(。

这是另一个例子:

int x; // global variable - always accessible as ::x
int main(int x, char** argv) { // this 'x' hides global 'x'
// This is the only place you can get at the argument 'x'
// before it is hidden by the line below.
int x; // this subsequently hides the function argument 'x'
{
int x; // hides the 'x' at function scope
for (int x = 0; x < 42; ++x) { // this 'hides 'x' in our nested scope
// The for loop induction variable 'x' is what's in scope here
}
// Now 'x' is again the nested-scope 'x'
}
// Here 'x' again refers to the function scope 'x'
}
// At any point in time you can get access to the 'x' that is directly
// in scope *or* the global 'x' (as '::x')
// But you cannot access the other 'x's until you are back in
// their respective scopes.

但尽量避免做上述事情。它很快导致混乱和错误。

通过这样做,您可以在功能块中隐藏全局名称。

void print_X(const X& X, const X& Y)  //won't compile
void print_X(const X& X){
X myX;    //again, won't compile
}

用斯特劳斯特鲁普的话说:*

块中名称的声明可以隐藏 封闭块或全局名称。也就是说,可以将名称重新定义为 引用块中的其他实体。退出街区后, 该名称恢复了其先前的含义。


*Stroustrup: The C++ Programming Language, 4th Edition;第 6.3.4 节 范围;157 页