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

时间:2015-10-26 15:49:03

标签: c++ sizeof

#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; 
} 

上述代码返回:C::f() = 8, ::f() = 4

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

结论:从我在https://stackoverflow.com/a/612476/1021388中读到的内容,按函数/对象/枚举器名称隐藏类名是为了兼容性问题C.为了避免这种无意隐藏,应该typedef强制编译错误的类。

3 个答案:

答案 0 :(得分:20)

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

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

  
      
  1. ... snip ...如果在声明了同名变量,函数或枚举数的作用域中声明了类名,那么当两个声明都在作用域中时,该类只能被引用使用精心设计的说明符。
  2.   

有一个名为C的类和一个全局范围内同名的变量。因此,只能使用精心设计的类型说明符(class C)来引用该类。

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

§9.1[class.name]:

  
      
  1. 类声明将类名引入声明它的范围,并在封闭范围内隐藏该名称的任何类,变量,函数或其他声明... snip ...
  2.   

§9[class]:

  
      
  1. ... snip ...类名也插入到类本身的范围内;这被称为inject-class-name ... snip ...
  2.   

因此,在class C的范围内,注入的类名隐藏了外部作用域的int C声明。因此,您可以参考C而无需详细说明类型说明符。要引用全球int C,您可以使用::C

答案 1 :(得分:3)

关于您的问题,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";
} 

答案 2 :(得分:1)

尝试编译此代码将为您提供答案

-e DISPLAY
#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