当我尝试编译以下代码时,出现此错误消息:
错误:声明在全局范围内隐藏了一个变量:
void迭代器(节点*根)
我不知道我到底在哪里隐藏或遮盖了之前声明的全局变量。
我该如何解决?
// typedef node
typedef struct node
{
bool is_word;
struct node* children[27];
}
node;
node* root = NULL;
void iterator(node* root)
{
for(int i = 0; i < 27; i++)
{
if (root -> children[i] != NULL)
{
iterator(root -> children[i]);
}
}
free(root);
return;
}
答案 0 :(得分:1)
编译器错误消息;在C标准中没有定义“全局范围”。它试图告诉您的是:
node* root = NULL;
将root
声明为文件范围的标识符(从其声明到翻译单元(正在编译的源文件)末尾都可见),并且:
void iterator(node *root)
将root
声明为块范围内的标识符(从其声明到定义函数的块末尾都可见)。
这些声明引用了两个不同的对象。第一个是具有静态存储持续时间的对象-只要程序正在执行,它就一直存在。第二个是函数参数-仅在函数执行时存在,并且每次调用函数时都有一个单独的实例。
在函数内部,root
仅引用函数参数。前一个声明是隐藏的,并且函数内部的任何代码均不能使用其名称引用该声明。 (这是编译器错误消息中的另一点草率; C标准使用“隐藏”,而不是“阴影”。)
关于C标准,这没有错-允许您隐藏标识符。但是,对于人类而言,这可能会引起问题,因为一个人可能在一个地方写root
,而打算在另一地方引用root
,因为他们没有看到或忘记第二个声明。 。这就是为什么编译器可能对此有可选警告的原因。看来您正在启用警告的情况下进行编译,并且具有将警告提升为错误的选项。
要解决此问题,您应该为静态对象和函数参数使用不同的名称,或者关闭编译器警告以隐藏标识符,无论您认为哪种方式适合您的项目。