为什么sizeof(x+;+;)不增加x? 这里是在DEVC++窗口中编译的代码: #include <stdio.h> int main() { int x = 5; printf("%d and ", sizeof(x++)); // note 1 printf("%d\n", x); // note 2 return 0; }

为什么sizeof(x+;+;)不增加x? 这里是在DEVC++窗口中编译的代码: #include <stdio.h> int main() { int x = 5; printf("%d and ", sizeof(x++)); // note 1 printf("%d\n", x); // note 2 return 0; },c,sizeof,C,Sizeof,有人能解释为什么x在注释1之后不递增吗?sizeof是一个编译时运算符,因此在编译时sizeof及其操作数将被结果值替换。操作数根本不计算(变长数组除外);只有结果的类型才重要 输出: 2 asshort在我的机器上占用2个字节 将函数的返回类型更改为双精度: double func(short x) { // rest all same 将给出8作为输出。来自(重点是我的) 6.5.3.4/2 sizeof运算符生成其操作数的大小(以字节为单位),可以是表达式或类型的括号名称。大小由操作数

有人能解释为什么
x
注释1之后不递增吗?

sizeof
是一个编译时运算符,因此在编译时
sizeof
及其操作数将被结果值替换。操作数根本不计算(变长数组除外);只有结果的类型才重要

输出:

2
as
short
在我的机器上占用2个字节

将函数的返回类型更改为双精度:

double func(short x) {
// rest all same
将给出
8
作为输出。

来自(重点是我的)

6.5.3.4/2

sizeof运算符生成其操作数的大小(以字节为单位),可以是表达式或类型的括号名称。大小由操作数的类型决定。结果是一个整数。如果操作数的类型是可变长度数组类型,则对操作数求值;否则,不计算操作数,结果为整数常量

sizeof(foo)
非常努力地在编译时发现表达式的大小:

6.5.3.4:

sizeof运算符生成其操作数的大小(以字节为单位),该操作数可以是 表达式或类型的括号名称。大小由类型决定 操作数。结果是一个整数。如果操作数的类型是可变长度数组 类型,则计算操作数;否则,不计算操作数,结果为 整数常量


简而言之:可变长度数组,在运行时运行。(注意:是一个特定的特性——不是分配给malloc(3)的数组)否则,只计算表达式的类型,并且在编译时计算表达式的类型。

sizeof
是编译时内置的运算符,不是函数。在不使用括号的情况下,这一点变得非常清楚:

(sizeof x)  //this also works

编译期间无法执行。所以
++i
/
i++
不会发生。另外,
sizeof(foo())
将不执行函数,而是返回正确的类型。

由于未计算
sizeof
运算符的操作数,您可以执行以下操作:

int f(); //no definition, which means we cannot call it

int main(void) {
        printf("%d", sizeof(f()) );  //no linker error
        return 0;
}
在线演示:

也就是说,如果只在
sizeof
中使用函数,则不需要定义函数
f
。该技术主要用于C++模板元编程,即使C++中,也不计算<代码> SIEZOOS的操作数。 为什么这样做有效?它之所以能工作,是因为
sizeof
运算符不对值进行操作,而是对表达式的类型进行操作。因此,当您编写
sizeof(f())
时,它会对表达式
f()
的类型进行操作,而这只是函数
f
的返回类型。无论函数实际执行时返回什么值,返回类型始终相同

在C++中,你甚至可以这样:

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;
}
结构A { A();//没有定义,这意味着我们无法创建实例! int f();//没有定义,这意味着我们不能调用它 }; int main(){ std::cout
sizeof()
运算符只给出数据类型的大小,不计算内部元素。

注意

这个答案是从一个副本中合并而来的,这解释了日期晚的原因

原创的

除sizeof外,sizeof不评估其参数。我们可以从C99标准草案第6.5.3.4节《sizeof运算符》第2段中看到这一点,其中指出:

sizeof运算符生成其操作数的大小(以字节为单位),该操作数可以是 表达式或类型的括号名称。大小由类型决定 操作数。如果操作数的类型是可变长度数组,则结果为整数。 类型,则计算操作数;否则,不计算操作数,结果为 整数常量。

一条评论(现已删除)询问这样的内容是否会在运行时进行评估:

sizeof( char[x++]  ) ;
事实上,这样的事情也会起作用():

因为它们都是可变长度的数组。尽管如此,我看不出这两种数组有多大的实际用途

注:
6.7.5.2节
数组声明器第4段中介绍了可变长度数组:

[…]如果大小是整数常量表达式,并且元素类型具有已知的常量大小,则数组类型不是可变长度数组类型;否则,数组类型是可变长度数组类型。

更新

在C11中,VLA情况的答案会发生变化,在某些情况下,大小表达式是否被计算是未知的。从
6.7.6.2
数组声明符部分可以看出:

[…]其中大小表达式是sizeof的操作数的一部分 运算符和更改大小表达式的值将不起作用 是否影响运算符的结果,未指定是否 计算大小表达式

例如,在这样的情况下():


<代码>代码> >代码>运行时,但代码> > X++>代码>只能在运行时进行评估。为了解决这个问题,C++标准规定<代码> SigeOS< <代码>的操作数没有被评估。 如果[of
sizeof
]的操作数类型为可变长度数组类型,则对操作数求值;否则,不对操作数求值,结果为整数常量


变长数组类型是什么意思?这确实意味着操作数是数组?本例中的代码不是数组。您能帮我澄清一下吗?变长数组是一个声明的数组,其大小在编译过程中是未知的,例如,如果您从stdin读取
N
,并生成
int-array[N]这是C99的一个特性,在C++中不可用。
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( char[x++]  ) ;
sizeof( char[func()]  ) ;
sizeof( int (*)[x++] )