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

时间:2009-10-17 09:41:42

标签: c++ c sizeof

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

例如,如果你这样写:

int i=0;
printf("%d\n", sizeof(++i));
printf("%d\n", i);

您可能会得到如下输出:

4
0

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

movl     $4, %esi
leaq     LC0(%rip), %rdi
xorl %eax, %eax
call     _printf

因此,编译器直接将常量“4”作为printf的参数添加调用它。那么sizeof做了什么?

9 个答案:

答案 0 :(得分:34)

你知道,有standard documents (3.8MB PDF)的原因; C99,第6.5.3.4节,第2节:

  

sizeof运算符产生大小   (以字节为单位)其操作数,可以   是一个表达式或括号   类型的名称。尺寸确定   从操作数的类型。该   结果是一个整数。如果是这种类型的   操作数是一个可变长度数组   type,操作数被评估;   否则,操作数不是   评估,结果是整数   恒定


回应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));
}

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

答案 1 :(得分:16)

sizeof是一个运算符,而不是函数。

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

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

int i=0;
cout << sizeof(++i) << endl;
cout << i << endl;

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

int myVal;
cout << sizeof myVal << endl;
cout << sizeof(myVal) << endl;

是等效的。

答案 2 :(得分:8)

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

由于类型的大小在编译时始终是已知的,因此它将作为常量放入机器代码中。

答案 3 :(得分:2)

在编译时将它替换为常量(在您的情况下为4)。因为在你的平台上持有一个int需要4个字节。

你的代码不会编译,而不是给你任何输出;-)因为sizoef; - )

答案 4 :(得分:1)

返回类型的大小是在编译时计算的,没有运行时开销

答案 5 :(得分:1)

在C ++中sizeof()计算其中表达式类型的大小,并在编译期间用常量替换整个“sizeof()函数调用”。

在程序执行期间永远不会评估sizeof()中的表达式。它甚至可能不是类型名称。请查看以下示例:

struct X { int i; double j;};
int call_to_undefined_function();

sizeof(10/0);
sizeof( ((struct X*)NULL)->j );
sizeof( call_to_undefined_function() + 100 );
sizeof( call_to_undefined_function() + 100.0 );
sizeof( double() / int() );

答案 6 :(得分:0)

究竟是什么意思:直接将常量“变量/常量/类型/等的大小”放入代码中

答案 7 :(得分:0)

sizeof()返回作为参数传递给它的任何内容的大小(以字节为单位)。 在32位体系结构中,sizeof(int)将返回4,而sizeof(char)将返回1.

答案 8 :(得分:0)

你自己说:'sizeof'不是一个功能。它是一个具有特殊语法和语义的内置运算符(请参阅前面的响应)。为了更好地记住它不是一个函数,你可能想要摆脱使用多余括号的习惯,而更喜欢使用带有表达式的“无括号”'sizeof',如下例所示

printf("%d\n", sizeof ++i);

这与原始版本完全相同。