为什么将sizeof称为编译时运算符?


12

本来这是另一个问题的一部分。

为什么sizeof称为编译时运算符?它实际上不是运行时运算符吗?而且,如果它确实是一个编译时运算符,那么它如何帮助产生在不同计算机上运行相同代码的可移植代码?请详细说明。



3
您如何期望类型的大小在运行时发生变化?

@MichaelT:类型实例的大小当然可以改变-毕竟有类多态性。我认为sizeof(polymorphic_ptr*)保持不变是违反直觉的,只是愚蠢的。是的,这是C ++方式,但是很愚蠢。
恢复莫妮卡

@KubaOber确实。我很好奇,OP认为它在不同情况下应该如何工作,并希望获得一些代码,以证明他对此感到困惑,以帮助扩大问题。

4
来了“由于它在编译时运行”的答案,这让他很失望。
本杰克逊

Answers:


23

sizeof()给您数据类型的大小,而不是内存中该类型的特定实例的大小。

例如,如果您有一个字符串数据对象,该对象在运行时分配了一个可变大小的字符数组,则sizeof()不能用于确定该字符数组的大小。它只会给你指针的大小。

数据类型的大小在编译时总是已知的。


3
因为C(++)没有运行时对象元数据,所以您也无法在运行时真正获得这些东西。
C. Ross

5
实际上,如果sizeof在数组上使用,则将获得数组的大小(即元素大小乘以元素数)。但是,如果在指针上使用它,则只会得到指针的大小。因此,由于在大多数情况下您想知道数组的大小,所以只有一个指针,所以它并不是那么有用。
sepp2k 2013年

1
@Jens该问题被标记为[C ++],并且VLA并未将其纳入C ++标准。
authchir

13

因为“调用”的整个sizeof是在编译时计算的,并且括号之间的所有内容都将被丢弃,并且不会在运行时运行,

结果完全基于编译器可用的静态类型信息


7

为什么将sizeof称为编译时运算符?

因为在编译时,编译器会计算表达式的大小并替换该编译时常量值。

它实际上不是运行时运算符吗?

不会。您甚至可以使用它sizeof来评估无法合法执行的表达式的大小(即,这将导致未定义的行为),只要编译器可以弄清楚表达式的类型是什么即可。

同样,即使在C ++ 11之前constexpr,您也可以使用sizeof无法使用运行时表达式的方式来使用表达式。

如果确实是一个编译时运算符,它如何有助于产生可移植的代码...

在不同平台上,类型的大小可能有所不同。使用sizeof表达式而不是硬编码的假设意味着在其他平台上进行编译并且类型更改大小时,代码不会中断。


1
好吧,我发现这是最有用的答案;)。兄弟(假设你是男性),我对此表示怀疑。您的意思是说,当人们说sizeof使程序可移植时,它们的意思是可以在所有计算机上编译源代码而没有任何错误,也不意味着可执行程序可以在任何计算机上运行。对 ?如果这是正确的话,我的疑虑就会被清除。
和平编码员

1
是的,代码是可移植的,从某种意义上说,您可以为每个平台编译一个(不同的)正确的二进制文件。
无用的

5

C ++实际上不在运行时存储对象的元数据,因此大小检查必须在编译时进行。有关C ++如何不验证大小的示例,请声明一个int任意大小的数组,然后读取其末尾。如果幸运的话,您会得到一个segfault但更可能的原因,只是阅读乱码,因为C ++不会跟踪数组的大小。

请参阅C / C ++程序段错误是否可以读取数组末尾(UNIX)?以SO为例。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.