C中的命名空间查找顺序

Namespace lookup order in C

名称space是否有查找顺序,即标签名称space普通名称space?考虑以下代码:

#include <stdio.h>

int main (void){

  typedef struct{ //This belongs to ordinary name space
    int min;
  } st;
  st myst;
  myst.min=6;
  struct myst{ // This belongs to tag name space
    int min;
  };
  myst.min=7;
  printf("%d\n%d\n",myst.min,myst.min);
  return 0;
}

输出

7

7

编译器首先在标签名称space中查找要打印的变量,我猜。我不知道查找是否甚至针对普通名称中的相同标识符完成space,如果完成了我不知道为什么它不打印它。

C 中没有名称空间查找顺序。对于任何特定标识符,只会考虑一个名称空间;它由正在查找的标识符类型决定。结构标签是一种,有自己的命名空间;变量名属于更广泛的 "ordinary identifiers" 类别,它们具有单独的命名空间。也有其他名称空间,但编译器总是可以从上下文中分辨出哪个名称空间与任何给定标识符相关。

因此,在您的程序中,myst.min 的两次使用都引用声明为 st myst; 的变量,并且 "tag" 命名空间中没有任何第二个变量(如您所见以为会有)。

您可以通过在 myst.min = 7:

上方注释掉 main 内的所有内容来亲眼看到
#include <stdio.h>

int main (void){
#if 0
  typedef struct{ //This belongs to ordinary name space
    int min;
  } st;
  st myst;
  myst.min=6;
#endif
  struct myst{ // This belongs to tag name space
    int min;
  };
  myst.min=7;
  printf("%d\n%d\n",myst.min,myst.min);
  return 0;
}

尝试编译它会产生硬错误:

test.c: In function ‘main’:
test.c:14:3: error: ‘myst’ undeclared (first use in this function)

struct myst 声明所做的是声明另一个 type,然后您可以使用它来声明变量。但除非你真的这样做,否则它不会用于任何事情。例如

#include <stdio.h>

typedef struct { int min; } st;
struct myst { int min };
int main(void)
{
    // uses the typedef name 'st', in the ordinary namespace,
    // to declare the variable 'myst', also in the ordinary namespace
    st myst = { 6 };

    // uses the struct name 'myst', in the tag namespace,
    // to declare the variable 'myst2', in the ordinary namespace
    struct myst myst2 = { 7 };

    printf("%d %d\n", myst.min, myst2.min);
    return 0;
}

将打印 6 7。该程序还说明了变量 myst 和结构标记 myst 确实位于两个不同的命名空间中并且可以独立引用。


(感谢 John Bollinger 提供新的第一段。-ed)

C 名称空间完全不相交。每个标识符仅在一个名称空间中搜索。例如:

  • structunion 关键字后的标识符在标记命名空间中搜索
  • goto 关键字后的标识符在标签命名空间中搜索
  • .-> 符号之后的标识符在它们的结构或联合成员命名空间中搜索(每个结构和联合都有自己的成员命名空间;前面表达式的类型决定了搜索哪个)
  • 在普通命名空间中搜索其他标识符。

没有查找顺序。要搜索的(唯一)名称空间完全由上下文决定。