为什么相同标识符的大小在 C 和 C++ 中不同?

Why does the size of the same identifier differ in C and C++?

#include <stdio.h>
int T;
int main()
{
    struct T { double x; };  
    printf("%zu", sizeof(T));
    return 0;
}

如果我在 C 中 运行 这段代码,结果是 4,而在 C++ 中它是 8

谁能解释一下为什么会这样?

我相信 C 指的是您需要编写的结构 struct T 而在 C++ 中,因为结构是 public class 它可以被称为只是 T 所以两者都只是采用了他们拥有的 T 的最本地定义。

简答:因为它们实际上不是同一个标识符。

在C中,结构名和变量名属于different namespaces,所以在C中,

sizeof(T) == sizeof(int) // global variable T
sizeof(struct T) == sizeof(struct T) // not the same namespace

然而,在 C++ 中,structure/class 名称进入 与变量相同的名称空间The "nearest" (most local) name is the result of name lookup,所以现在

sizeof(T) == sizeof(struct T) // structure T
sizeof(::T) == sizeof(int) // Note the scope resolution operator

因此结果分别是 4 和 8。

在 C++ 中,您可以用 sizeof(::T) 得到 4。 "double-colon" 范围解析运算符强制编译器将 T 作为外部命名空间中的名称,因此 ::T 是您想要的 int 类型的变量。


在 C 中,(structures/unions/enums) 和 (variables/functions/typedefs) 有独立的命名空间,因此您可以编写此代码而不用担心名称冲突。

struct T T;

注意括号,结构、联合和枚举共享一个命名空间,而其他三个共享另一个。

如果您尝试在 C++ 中执行此操作,您将立即 运行 遇到问题。


我喜欢。他明白了根本原因是 C 和 C++ 是不同的语言,尽管它们有相似之处。

您得到的结果不同,因为 C 和 C++ 是不同的语言。

在 C++ 中,当您声明一个结构(一个特殊的 class)时,

struct T { 
    double x; 
};  

然后你就可以把它当作

T sobj;  // sobj is an object of type T

T 是这里的类型。 而在 C 中,T 不是类型,而 struct T

struct T sobj; 

现在在 C++ 中使用 sizeof(T)sizeof(struct T),在 C 中使用 sizeof(struct T),它们会给你结构的大小。

在 C 中,struct T 中的 T 是一个 struct 标签。结构标记位于与变量和类型不同的名称空间中。要在 C 中获取类型,您必须编写 struct T

sizeof() 需要类型或表达式,而结构标签两者都不是。但是,您有变量 T。变量名称是 sizeof().

中的有效表达式

然而,在 C++ 中,struct T 中的 T 是类型名称,因为 C++ 中的结构本质上只是具有所有成员 public 的 class。因此 sizeof(T) 匹配 C++ 中的结构类型。


这里值得注意的是 sizeof 运算符有两种不同的语法情况:

sizeof 一元表达式
sizeof (类型名称)

如果是前者,sizeof 只接受表达式,不接受类型。对于后者,它不包括表达式或类型。所以如果你写 sizeof T 而不是 sizeof (T),你会在 C++ 中得到一个编译器错误,因为 T 将是一个类型而不是表达式。