代码:
int main()
{
extern int a;
int b;
cout<<sizeof(a)<<endl;
cout<<sizeof(b)<<endl;
}
输出:
4
4
如果我们只是声明一个变量,它不应该为该变量分配内存(?)。那么编译器如何不给出错误
cout<<sizeof(a)<<endl;
或者为什么程序没有崩溃?
代码:
int main()
{
extern int a;
int b;
cout<<sizeof(a)<<endl;
cout<<sizeof(b)<<endl;
}
输出:
4
4
如果我们只是声明一个变量,它不应该为该变量分配内存(?)。那么编译器如何不给出错误
cout<<sizeof(a)<<endl;
或者为什么程序没有崩溃?
sizeof
不需要评估您传递给它的表达式,只需要评估它的类型。外部定义extern int a
足以弄清楚类型,所以sizeof
成功了。
此外,由于内部的表达式sizeof
没有被评估,程序链接没有错误。
sizeof
在编译时解决。编译器所需要的只是一个具有完整类型的声明——它不需要为对象分配存储空间。
由于sizeof
表达式是在编译时解析的,因此也无法检查对象是否实际上是在另一个编译单元中定义的。如果我们想要这个检查,我们无法sizeof
在编译时进行评估(我们必须将它推迟到链接时),而且这种延迟根本没有充分的理由。
编译器知道它int
的大小为 4,并且在编译后没有任何东西可以给出int
另一个大小。正因为如此,成为sizeof(a)
了。sizeof(int)
4
sizeof() 不是一个函数,它是一个语言关键字,它解析为一个编译时间常数。
所以-您不是在访问或使用“a”,而是在向编译器询问有关您提供的有关“a”的信息之一的问题。
cout << sizeof( a ) << endl:
实际上是
cout << sizeof decltype(a) << endl;
实际上是
cout << sizeof int << endl;
实际上是
cout << 4 << endl;
您可以通过查看程序集输出来验证这一点。在 Linux 下,使用 GCC 或 Clang,
c++ -Wall -o test.S -S test.cpp
将生成汇编文件供您检查。
extern int a
你只是告诉编译器在某处有(应该是)一个名为type的a
变量。int
但是,您唯一要做的就是申请sizeof
它。现在编译器不需要访问a
就知道它的大小:既然你告诉编译器a
是 type int
,它已经知道它的大小:所有int
s 的大小都是一样的。
至于为什么编译器没有给出错误:实体的缺失定义extern
只有在实际使用该实体时才会给出错误。由于sizeof
不使用它,而只告诉您大小,因此您不会收到编译器错误。
因为它获取的是变量类型的大小,而不是实际使用的内存的大小(应该是相同的)。
int main () {
int a = 2;
std::cout << sizeof ((char) a) << std::endl; // Outputs 1
return 0;
}