sizeof 是 compile-time operator ,因此在编译时 sizeof 并且其操作数被结果值替换 . 操作数是 not evaluated (除非它是一个可变长度数组);只有 type 的结果很重要 .
short func(short x) { // this function never gets called !!
printf("%d", x); // this print never happens
return x;
}
int main() {
printf("%d", sizeof(func(3))); // all that matters to sizeof is the
// return type of the function.
return 0;
}
struct A
{
A(); //no definition, which means we cannot create instance!
int f(); //no definition, which means we cannot call it
};
int main() {
std::cout << sizeof(A().f())<< std::endl;
return 0;
}
然而看起来,在 sizeof 中,我首先通过编写 A() 来创建 A 的实例,然后通过编写 A().f() 来调用实例上的函数 f ,但是没有发生这样的事情 .
9 回答
来自C99 Standard(重点是我的)
sizeof
是 compile-time operator ,因此在编译时sizeof
并且其操作数被结果值替换 . 操作数是 not evaluated (除非它是一个可变长度数组);只有 type 的结果很重要 .输出:
因为
short
在我的机器上占用2个字节 .将函数的返回类型更改为
double
:将
8
作为输出 .sizeof(foo)
尝试在编译时很难发现表达式的大小:6.5.3.4:
简而言之:可变长度数组,在运行时运行 . (注意:Variable Length Arrays是一个特定的功能 - 不是用
malloc(3)
分配的数组 . )否则,只计算表达式的类型,并在编译时计算 .sizeof
是一个编译时内置运算符,不是函数 . 在没有括号的情况下可以使用它变得非常清楚:Note
这个答案是从一个副本合并而来,这解释了迟到的日期 .
Original
除variable length arrays之外,sizeof不评估其参数 . 我们可以从C99标准部分草案中看到这一点
6.5.3.4
运营商第2段的尺寸说:评论(现已删除)询问是否会在运行时评估此类内容:
事实上,这样的事情也会奏效(See them both live):
因为它们都是可变长度数组 . 虽然,我认为其中任何一个都没有太多实际用途 .
注意,draft C99 standard部分
6.7.5.2
数组声明符第4段中介绍了可变长度数组:Update
在C11中,VLA案例的答案发生了变化,在某些情况下,未指定是否评估了大小表达式 . 来自
6.7.6.2
部分的数组声明符说:例如,在这种情况下(see it live):
由于未评估
sizeof
运算符的操作数,您可以执行以下操作:在线演示:http://ideone.com/S8e2Y
也就是说,如果仅在
sizeof
中使用它,则不需要定义函数f
. 这种技术主要用于C模板元编程,因为即使在C中,也不会评估sizeof
的操作数 .为什么这样做?它起作用,因为
sizeof
运算符不对值进行操作,而是对表达式的类型进行操作 . 因此,当您编写sizeof(f())
时,它会对表达式f()
的类型进行操作,这只是函数f
的返回类型 . 返回类型总是相同的,无论函数在实际执行时返回什么值 .在C中,你甚至可以这样:
然而看起来,在
sizeof
中,我首先通过编写A()
来创建A
的实例,然后通过编写A().f()
来调用实例上的函数f
,但是没有发生这样的事情 .演示:http://ideone.com/egPMi
这是另一个解释
sizeof
的其他有趣属性的主题:编译期间不能执行 . 所以
++i
/i++
不会发生 . 此外sizeof(foo())
不会执行该功能但返回正确类型 .sizeof()
运算符仅给出数据类型的大小,它不计算内部元素 .sizeof
在编译时运行,但x++
只能在运行时进行评估 . 为了解决这个问题,C标准规定不评估sizeof
的操作数(除了VLA) . C标准说: