【问题标题】:Namespace lookup order in CC中的命名空间查找顺序
【发布时间】:2017-09-20 19:40:14
【问题描述】:

命名空间中是否存在查找顺序,即 标记命名空间普通命名空间 ?考虑以下代码:

#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

我猜,编译器首先会在标签命名空间中查找要打印的变量。我不知道是否对普通命名空间中的相同标识符进行了查找,如果完成了,我不知道为什么它不打印它。

【问题讨论】:

  • “编译器首先在标签命名空间中查找要打印的变量” - 不,它没有。您没有指定标签关键字。
  • 不清楚。仅在您指定的名称空间中搜索名称。顺便说一句:没有“标签名称空间”。
  • @StoryTeller 标签关键字?没有得到你。 struct 是标签名称。
  • 没有。 struct 是一个kewyrod。 struct id 告诉编译器你想要一个标记类型,并且它应该在标记命名空间中查找 id
  • @StoryTeller 当然struct 是一个关键字,如果没有使用typedef 定义,它会进入标签命名空间。

标签: c namespaces name-lookup


【解决方案1】:

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

因此,在您的程序中,myst.min 的两种用法都引用了声明为 st myst; 的变量,并且“tag”命名空间中没有任何第二个变量(您似乎认为会有)。

您可以通过注释掉main 上方myst.min = 7 上方的所有内容来亲眼看到这一点:

#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)

【讨论】:

  • 实际上定义相同的名称会导致冲突。仍然对查找顺序感到困惑。
  • @0decimal0,没有查找顺序。任何特定标识符都只考虑一个命名空间;它由正在查找的标识符类型决定。结构标签是一种,有自己的命名空间;变量名称属于更广泛的“普通标识符”类别,它们具有单独的命名空间。还有其他名称空间,但编译器总是可以从上下文中判断哪个名称空间与任何给定标识符相关。
  • 谢谢@JohnBollinger,我现在明白了。
  • @JohnBollinger 我可以将您的评论复制到我的答案文本中吗?
  • 当然,@zwol,我没有异议。
【解决方案2】:

C 命名空间是完全不相交的。每个标识符只在一个命名空间中搜索。例如:

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

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

【讨论】:

  • 您的回答中肯而简洁,谢谢。赞成:)
猜你喜欢
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 2018-10-29
  • 2015-10-05
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多