结构成员标识符放在啥范围内?

Posted

技术标签:

【中文标题】结构成员标识符放在啥范围内?【英文标题】:In what scope is a struct member identifier put?结构成员标识符放在什么范围内? 【发布时间】:2011-07-13 16:09:45 【问题描述】:

C 规范说

有四种作用域:函数、文件、块和函数原型。

现在,如果我在任何函数之外执行以下操作

struct A 
  int x;
;

我的理解是标识符x 在文件范围内是可见的。正如规范所说,我们使用命名空间语法来访问成员

每个结构或联合对其成员都有一个单独的名称空间(通过用于通过 . 或 -> 运算符访问成员的表达式类型来消除歧义)

让我们通过添加一个函数让这更清晰

struct A 
  int x;
;

void f(void) 
  int i;

那么参与这个程序的表示的标识符、范围和命名空间是(N/A 是“不适用”):

file scope
==========================================
Ordinary  |  Members A  |  Tags  |  Labels
------------------------------------------
 f        | x           | A      | N/A
          |             |        |


function scope of f
=========================================
Ordinary  |  Members ? |  Tags  |  Labels
-----------------------------------------
 N/A      | N/A        | N/A    |
          |            |        |


block scope #1
=========================================
Ordinary  |  Members ? |  Tags  |  Labels
-----------------------------------------
 i        |            |        | N/A
          |            |        |

作用域层次是“块作用域#1”->“f的函数作用域”->“文件作用域”。

我曾经和一位 C 编译器作者交谈过,他说x 不在任何范围内。谁能解释一下这将如何工作?那么我们怎么能以任何方式引用x呢?进一步引用(强调我的):

标识符可以表示一个对象;一个函数;标记或结构的成员、联合或枚举;类型定义名称;标签名称;宏名;或宏参数。

同一个标识符可以在程序的不同点表示不同的实体。

对于标识符指定的每个不同实体,标识符仅在称为其范围的程序文本区域内可见(即可以使用)。

如果我们说结构的成员没有范围,那么它是不可见的,因此不能使用。但显然,我们可以使用结构成员。我错过了什么吗?

【问题讨论】:

【参考方案1】:

正如标准所说,它位于为 struct 类型创建的单独名称空间中。我认为这条规则是在 C89 中添加的。 Once upon a time,所有成员名称共享一个名称空间。

也许编译器编写者有点迂腐; 命名空间作用域不同。 struct 定义没有引入范围,因为它不包含变量;它拥有成员。

【讨论】:

我的表格图错了吗?我想知道嵌套是否相反(即命名空间,并且在命名空间内,有范围)。因为规范曾经说过“如果一个标识符在同一个命名空间中指定了两个不同的实体,则作用域可能会重叠。”,这似乎表明我的嵌套是错误的,因为它表明每个作用域的命名空间与其他作用域的命名空间不同。如何解决?【参考方案2】:

我认为在这种情况下它所指的范围是A。您通过SomeA.x引用成员,其中SomeA的类型为A。

【讨论】:

【参考方案3】:

xstruct A 创建的范围内,但A 在全局范围内。这就是“规范”所称的文件范围,但名称具有误导性,因为您包含的所有文件都共享该范围。

【讨论】:

【参考方案4】:

作用域命名空间是两个完全不同的概念,不应混淆。

结构或联合的实例具有范围,但单个成员名称没有;范围的概念根本不适用于他们。

啊,我在考虑范围,而不是范围。

【讨论】:

一个标签有函数作用域,我们用goto labelname来引用它。结构成员具有其结构标记的范围(即块、文件或函数原型,取决于声明结构的位置),我们通过instance.membername 引用它。为什么不是这样?如果 membername 不在任何范围内,我们怎么能引用该成员呢? 我刚刚编辑了我的答案;我在考虑范围,而不是范围。但是,我仍然认为您混淆了不应混淆的概念,但我缺乏解释确切原因的技能。

以上是关于结构成员标识符放在啥范围内?的主要内容,如果未能解决你的问题,请参考以下文章

标识符不在范围内 [Unity, VS2019]

如何在块范围内声明具有内部链接的标识符,而无需事先声明该标识符且某些链接可见?

c语言枚举类型enum用法

C基础

我们啥时候需要将 using 指令放在命名空间范围内? [复制]

结构体中定义函数指针