sizeof 运算符是否更喜欢对象而不是类型?

Does sizeof operator prefer object over type?

#include <iostream> 

int C; 

class C { 
  private: 
    int i[2]; 
  public: 
    static int f() { 
        return sizeof(C); 
    } 
}; 

int f() 
{ 
    return sizeof(C); // why the C can't be the class type C.
} 

int main() 
{ 
   std::cout << "C::f() = " <<C::f() << "," 
             << " ::f() = " <<::f() << std::endl; 
} 

以上代码returns:C::f() = 8, ::f() = 4

我的问题是为什么全局函数 f 中的标识符 C 解析为名称为 C 的类型 int 的对象,而不是 class 类型Csizeof 是否有特定的名称查找规则?

结论:从我在这篇中读到的,用function/object/enumerator名字隐藏class名字是为了与C的兼容性问题。为了避免这种无意的隐藏,应该 typedef class 强制编译器错误。

关于您的问题,sizeof没有任何特殊的解析或评估规则。

考虑以下因素:

#include <iostream>
#include <typeinfo>

int C; 

class C { 
public:
    int i[2]; 
}; 

int main() 
{ 
   // compiles fine:
   int x = C;

   // prints 0:
   std::cout << C << "\n";

   // prints something that corresponds to "int"
   // (or even "int" itself):
   std::cout << typeid(C).name() << "\n";
}

在所有三种情况下,C 都被视为 int 变量而不是类型名称。

如果需要明确区分,可以随时使用class C:

#include <iostream>
#include <typeinfo>

int C; 

class C { 
public:
    int i[2]; 
}; 

int main() 
{ 
   // prints something that corresponds to "class C"
   // (or even "class C" itself):
   std::cout << typeid(class C).name() << "\n";

   // prints sizeof(int):
   std::cout << sizeof(C) << "\n";

   // prints sizeof(int) * 2:
   std::cout << sizeof(class C) << "\n";
} 

尝试编译这段代码会给你答案

#include <iostream>

int C;

class C {
    int i[2];
  public: 
    static int f() { 
        return sizeof(C); 
    }
}; 

int f() { 
    return sizeof(C); // why the C can't be the class type C.
} 

int main() {
   C a; // <-- Adding this line generates the error
   std::cout << "C::f() = " <<C::f() << "," 
             << " ::f() = " <<f() << std::endl; 
} 

prog.cpp:22:4: error: must use 'class' tag to refer to type 'C' in this scope
   C a;
   ^
   class 
prog.cpp:3:5: note: class 'C' is hidden by a non-type declaration of 'C' here
int C; 
    ^
1 error generated.

编译器:

clang version 3.7.0 (tags/RELEASE_370/final 246979)
Target: x86_64-unknown-linux-gnu
Thread model: posix

要获得正确的输出:

int f() { 
    return sizeof(class C);
} 

sizeof 不是这个问题的关键。它恰好是可以同时用于类型名称或变量名称的东西。这些规则也适用于标识符的其他用途。

§9.1 [class.name](c++ 标准草案 n3797):

  1. ...snip... If a class name is declared in a scope where a variable, function, or enumerator of the same name is also declared, then when both declarations are in scope, the class can be referred to only using an elaborated-type-specifier.

在全局范围内有一个名为 C 的 class 和一个同名变量。因此,只能使用详细的类型说明符 (class C).

来引用 class

然而,在 C 的定义中,该段的第一部分是相关的:

§9.1 [class.name]:

  1. A class declaration introduces the class name into the scope where it is declared and hides any class, variable, function, or other declaration of that name in an enclosing scope ...snip...

§9 [class]:

  1. ...snip... The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name ...snip...

因此,在 class C 的范围内,注入的 class 名称隐藏了外部范围的 int C 声明。因此,您可以在没有详细说明类型说明符的情况下引用 C。要引用全局 int C,您可以使用 ::C