8

看来 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 add 调用它的参数。那么 sizeof 是做什么的呢?

4

9 回答 9

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

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

于 2009-10-17T09:46:17.323 回答
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;

是等价的。

于 2009-10-17T10:21:31.537 回答
8

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

因为类型的大小在编译时总是已知的,所以将其作为常量放入机器代码中。

于 2009-10-17T09:43:59.077 回答
2

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

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

于 2009-10-17T09:44:59.857 回答
1

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

于 2009-10-17T09:45:04.083 回答
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() );
于 2009-10-17T09:53:54.470 回答
0

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

于 2009-10-17T09:44:55.743 回答
0

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

于 2009-10-17T09:45:48.107 回答
0

你自己说过:'sizeof' 不是一个函数。它是具有特殊语法和语义的内置运算符(参见前面的回复)。为了更好地记住它不是函数,您可能希望摆脱使用多余大括号的习惯,并更喜欢将“无括号”“sizeof”与表达式一起使用,如下例所示

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

这与您的原始版本完全相同。

于 2009-10-17T15:18:47.000 回答