在 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.8
、5.3.3
、5.3.7
、7.1.6.2
)。未计算的操作数不会被计算。
这里5.3.3
指的是sizeof
(其他是typeid
、noexcept
和decltype
)。
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) 表达式中未调用增量运算符 [重复]的主要内容,如果未能解决你的问题,请参考以下文章