在 sizeof(++n) 表达式中未调用增量运算符 [重复]

Posted

技术标签:

【中文标题】在 sizeof(++n) 表达式中未调用增量运算符 [重复]【英文标题】:Increment operator is not invoked at sizeof(++n) expression [duplicate] 【发布时间】:2014-12-11 19:04:15 【问题描述】:

在 C 或 C++ 中,递增和递减运算符(++n--n)在 sizeof() 运算符中时不会执行。

int n = 100;
int size_int = sizeof(++n);
std::cout<<n;

我已经编写了这段代码并运行了程序。当然,我认为 101 会为我展示。 但是,n 不是 101,而是 100。

这是为什么呢?

【问题讨论】:

sizeof 在编译时进行评估,这可以解释为什么编译器可能会出错,但我希望您发布的代码也可以编写 101。 应该是这样的; sizeof 不评估它的参数(除非它是一个 C 可变长度数组)。即使sizeof(* (int*) 3); 也是有效的(相当于sizeof(int))。 @remyabel 我的意思只是对你的“刚刚开始”的评论,其余的是给 OP。我知道你要么是在开玩笑,要么是在抱怨人们这样做:) 我已将问题编辑为仅涉及 C++。代码示例使用 C++ 编写。 Chere已经有问题了。 @hacks 投票重新开放。建议的副本仅适用于 C;而 C 在这方面与 C++ 不同。 【参考方案1】:

在 C++ 中,sizeof 中的表达式 被评估,除了 C99 的 VLA 如 cmets 中所述,因为这之前也标记为 C 支持>

sizeof 运算符是在编译时计算的。

只有表达式的类型(在编译时计算)被sizeof使用。

来自C++ Standard § 5.3.3 Sizeof

sizeof 运算符产生对象中的字节数 其操作数的表示。操作数要么是表达式,要么 这是一个 未计算 操作数(第 5 条),或带括号的 类型 ID。

一些 C++ 编译器提供 VLA 作为扩展 as commented below。

【讨论】:

@MattMcNabb 这是你说的 VLA 吗? 另外,() 不是操作员名称的一部分。跟着我重复,现在真的大声:sizeof 不是函数! @unwind:我意识到这曾经是一个“C/C++”问题;您现在可以删除您的反对票。 @phresnel 之前的 OP 也用 C 标记了问题 @Ryan Umm,如何这样做?大小是对象类型的属性。【参考方案2】:

在 C 中,sizeof 的操作数不会在除可变长度数组之外进行计算:

6.5.3.4。 p2:

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

如果你把n++放到一个变长数组中,例如:

int n = 1 ; 
sizeof( int(*)[n++] ) ;

如果操作数被求值,则未指定。

6.7.6.2。 p5

如果大小是一个不是整数常量表达式的表达式:如果它出现在一个 在函数原型范围内声明,它被视为被 * 替换;否则, 每次对其进行评估时,它的值都应大于零。每个实例的大小 可变长度数组类型在其生命周期内不会改变。 哪里有尺寸 表达式是 sizeof 运算符的操作数的一部分,并更改 size 表达式不会影响操作符的结果,不指定是否 评估大小表达式

【讨论】:

Maybe add 6.7.6.2 p5 (n1570) 如果大小表达式是 sizeof 运算符的操作数的一部分,并且更改大小表达式的值不会影响运算符,是否计算大小表达式是未指定的。 因此,例如在int n = 1; sizeof(int (*)[n++]) 中,是否评估n++ 是未指定的。 建议将此答案(包括mafso的评论)移至this thread【参考方案3】:

在 C++ 中,sizeof 不计算其操作数。

引用自 C++ 标准,部分 C++11 中的 [expr] 5/7 或 C++14 中的 [expr] 5/8

在某些情况下,会出现未计算的操作数(5.2.85.3.35.3.77.1.6.2)。未计算的操作数不会被计算。

这里5.3.3指的是sizeof(其他是typeidnoexceptdecltype)。

C++98 标准没有这一段,但无论如何在其 5.3.3 Sizeof 部分它声明与较新的标准基本相同:

sizeof 运算符在其操作数的对象表示中产生字节数。操作数要么是一个不计算的表达式,要么是一个带括号的type-id

【讨论】:

说哪个版本的标准更好 @MattMcNabb 成功了。【参考方案4】:

如果你检查了反汇编:

int size_int = sizeof(++n);

然后你会看到类似的东西(取决于你的编译器):

mov dword ptr [size_int],4

sizeof(...) 表达式在编译时进行评估,并替换为常量值。

在上面的示例中,sizeof(...) 表达式替换为的常量值为 4。

【讨论】:

以上是关于在 sizeof(++n) 表达式中未调用增量运算符 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

数组与文字

sizeof运算符及其表达式

具有可变长度数组类型的 Sizeof 运算符

sizeof 运算结果与编译系统有关

为啥 sizeof 被认为是运算符?

sizeof 运算符在 C 中接受哪些参数?