在 C 和 C++ 中,同一个标识符如何用于两个不同的事物?

How can a same identifier be used for two different things in C & C++?

抱歉,如果此类问题已在 SO 上提出,但这对我来说是新的,因为我尝试遵循简单的程序。

#include <stdio.h>
void foo()
{
    puts("foo() is invoked");
}
struct foo
{
    int a;
};
int main()
{
    struct foo f={3}; 
    printf("%d\n",f.a);
    foo();
}

我们不应该得到一个错误吗?如何在 C 和 C++ 中对函数和结构使用相同的标识符? C&C ++标准对此有何评论?

类型的名称是struct foo;即,当引用结构时,foo 总是以 struct 开头,因此它是明确的结构而不是函数。此外,由于这不是 C++,声明 struct foo 不会使 foo 成为类型的名称,因此普通的 foo 只能引用函数。如果您尝试这样做,您只会遇到问题:

typedef struct foo {
    int a;
} foo;

标签名称(对于结构、联合和枚举)占用与标识符(函数、对象和类型定义名称)不同的 名称 spacestructunionenum 关键字 1 消除了标签名称的歧义。

请注意,struct 和 union member 名称占用另一个名称space,并通过使用 . 或 [=19] 在表达式中消除歧义=] 组件选择运算符,所以下面的代码是合法的(如果真是个坏主意的话):

struct foo { int foo; };
struct foo foo;
foo.foo = some_value();

类型名称 struct foostruct 关键字消除歧义,成员名称 foo.foo. 运算符消除歧义。

以下是您不能做的事情:

  • 你不能对一个结构 一个联合,或者一个结构 一个枚举等使用相同的标签名称; IOW,你不能这样做:
    struct foo { ... };
    enum foo { ... };
    union foo { ... };
    
    在相同的代码中;
  • 不能对 typedef 名称对象名称使用相同的名称:
    typedef struct foo { int foo; double bar; } foo;
    foo foo;
    
  • 不能对枚举常量和对象名称使用相同的名称:
    enum blurga { foo, bar, bletch } foo;
    
  • 函数名和对象名不能使用相同的名称:
    int foo() { ... }
    int bar()
    {
      int foo = foo();
    }
    


1。我假设 C++ 中的 class 关键字也是这种情况,但我手头没有那个参考。