在C/C++中sizeof()的机制是什么?

ibr*_*ead 8 c c++ sizeof

看来sizeof不是真正的功能吗?

例如,如果你这样写:

int i=0;
printf("%d\n", sizeof(++i));
printf("%d\n", i);
Run Code Online (Sandbox Code Playgroud)

你可能得到如下输出:

4
0
Run Code Online (Sandbox Code Playgroud)

当你深入研究汇编代码时,你会发现这样的:

movl     $4, %esi
leaq     LC0(%rip), %rdi
xorl %eax, %eax
call     _printf
Run Code Online (Sandbox Code Playgroud)

所以,编译器直接将常量"4"作为printf的参数添加调用它.那尺寸做什么呢?

Chr*_*oph 34

你知道,这就是为什么有标准文件的原因(3.8MB PDF) ; C99,第6.5.3.4节,§2:

sizeof操作者产生其操作数的大小(以字节为单位),其可以是表达或类型的括号名称.大小由操作数的类型确定.结果是整数.如果操作数的类型是可变长度数组类型,则计算操作数; 否则,不评估操作数,结果是整数常量.


在回应ibread的评论时,这里是C99可变长度数组的一个例子:

#include <stdio.h>

size_t sizeof_int_vla(size_t count)
{
    int foo[count];
    return sizeof foo;
}

int main(void)
{
    printf("%u", (unsigned)sizeof_int_vla(3));
}
Run Code Online (Sandbox Code Playgroud)

foo在编译时不再知道大小,必须在运行时确定.生成的程序集看起来很奇怪,所以不要问我实现细节......

  • 这也是stackoverflow.com存在的原因. (21认同)
  • 从上面的片段中可能没有立即明显看出,任何函数调用或者大小中的副作用都采用VMT(可变修改类型)的大小,就像VLA的类型一样,如果对于确定它很重要,会导致副作用发生值:`int gimme(void){format("C:/"); 返回2; } int main(void){sizeof(int [gimme()]); }`.这实际上是格式:)相反,以下格式是否未指定:`sizeof((int(*)[format()])0)`:更改`format()`的值不会改变sizeof的结果(对于所有对象指针具有相同大小的impls). (2认同)

Joh*_*ter 16

sizeof 是一个操作员,而不是一个功能.

通常被评估为编译时 - 例外情况是它在C99样式的可变长度数组上使用.

您的示例是评估sizeof(int),当然在编译时已知,因此代码将替换为常量,因此++在运行时不存在以执行.

int i=0;
cout << sizeof(++i) << endl;
cout << i << endl;
Run Code Online (Sandbox Code Playgroud)

值得注意的是,由于它是一个运算符,因此可以在没有值的括号的情况下使用它:

int myVal;
cout << sizeof myVal << endl;
cout << sizeof(myVal) << endl;
Run Code Online (Sandbox Code Playgroud)

是等价的.


Tim*_*mbo 8

Sizeof分析传递的表达式以查找其类型.然后它返回类型的大小.

因为类型的大小在编译时始终是已知的,所以它作为常量放入机器代码中.

  • C++中的+1,以及C99之前的.在C99中,类型的大小在编译时并不总是已知:`void f(int N){int array [N]; printf("%d \n",sizeof(array)); }`.在这种情况下,数组的大小在编译时是未知的,但在运行时是已知的. (3认同)