[英]C: what is the name space of a type definition?
typedef名称在哪个名称空间中? 考虑以下代码:
#include <stdio.h>
typedef struct x { // 'x' in tag name space
int x; // 'x' in member name space
int y;
} x; // ??
int main() {
x foo = { 1, 2 };
int x = 3; // 'x' in ordinary identifier name space
printf("%d %d %d\n", foo.x, foo.y, x);
}
这将使用gcc 4.4.7(和g ++ 4.4.7)打印出“ 1 2 3”,因此类型名称与标记,成员和普通标识符名称分开。
此代码还可以在gcc / g ++ 4.4.7上编译并运行,产生“ 1、2”:
#include <stdio.h>
typedef struct x { // 'x' in tag namespace
int x; // 'x' in member namespace
int y;
} x;
int main() {
x x = { 1, 2 };
printf("%d %d\n", x.x, x.y);
}
在这种情况下, x
标识符如何消除歧义?
编辑 ,我希望澄清。 从上面考虑这两行:
x foo = { 1, 2 };
int x = 3; // 'x' in ordinary identifier name space
当执行第二行时,标识符x
在范围内,并且在逻辑上应位于“普通标识符”名称空间中。 此时似乎没有新的作用域,因为在第1行和第2行之间没有开括号。因此,第二个x
不能隐藏第一个x
,而第二个x
是错误的。 这个论点有什么缺陷,这对xx
案例有何意义? 我的假设是,缺陷在于类型名称在某种程度上具有不同的非显而易见的名称空间,因此是该问题的标题。
它的作用不是由于名称空间(新的类型名称和变量标识符在同一普通名称空间中),而是由于作用域。
6.2.1标识符范围
2对于标识符指定的每个不同实体,该标识符仅在称为其作用域的程序文本区域内可见(即可以使用)。 由同一标识符指定的不同实体要么具有不同的范围,要么处于不同的名称空间中。 范围有四种:函数,文件,块和函数原型。 (函数原型是声明其参数类型的函数的声明。)
4每个其他标识符的范围都由其声明的位置(在声明程序或类型说明符中)确定。 如果声明标识符的声明符或类型说明符出现在任何参数块或参数列表之外,则标识符具有文件作用域,该文件作用域终止于转换单元的末尾。 如果声明标识符的声明者或类型说明符出现在功能定义的块内或参数声明列表中,则标识符具有块作用域,该作用域终止于相关块的末尾。 如果声明标识符的声明器或类型说明符出现在函数原型的参数声明列表中(不是函数定义的一部分),则标识符具有函数原型范围,该范围终止于函数声明符的末尾。 如果标识符在同一名称空间中指定两个不同的实体,则范围可能会重叠。 如果是这样,一个实体的范围(内部范围)将严格在另一实体的范围(外部范围)之前结束。 在内部范围内,标识符指定在内部范围内声明的实体; 在外部范围内声明的实体在内部范围内隐藏(不可见)。
名为x
的变量是内部作用域。 因此,它在外部范围中隐藏了名为x
的实体。 在main
的作用域内,在声明xx
,它是一个变量名。
有趣的是xx = { 1, 2 };
x
的含义在声明中更改。 首先,它表示类型名称,但是一旦声明器引入标识符, x
开始表示变量。
关于您的修改“此参数有何缺陷?” 请注意,范围可能会重叠(如上一段所述)。 类型别名的定义实际上是在文件范围内。 main的块作用域是与外部作用域重叠的新内部作用域。 这就是为什么它可以用来隐藏x
的先前含义的原因。 您是否尝试过在文件范围内执行此操作:
typedef struct x { /* ... */ } x;
int x = 1; // immediately at file scope
它将是错误的形式。 因为现在声明确实出现在完全相同的范围内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.