【发布时间】:2023-02-02 21:00:13
【问题描述】:
我的项目要求完全了解 sizeof 运算符的实际工作原理。在这方面的 C 标准规范是模糊的,依赖我对它的解释是危险的。我特别感兴趣什么时候和如何sizeof 应该被处理。
- 我以前的知识表明它是一个编译时运算符,我从未质疑过这一点,因为我从未过度滥用
sizeof。然而:int size = 0; scanf("%i", &size); printf("%i\n", sizeof(int[size]));例如,这不能在编译时以任何方式进行评估。
char c = '\0'; char*p = &c; printf("%i\n", sizeof(*p));我不记得产生 U/B 的确切代码,但在这里,
*p是一个实际的表达式(RTL 一元取消引用)。据推测,这是否意味着sizeof(c+c)是一种通过表达式强制进行编译时评估的方法,还是会被编译器优化?-
sizeof是否返回int类型的值,它是size_t(在我的平台上是 ULL),还是实现定义的。 -
This 文章指出“
sizeof的操作数不能是类型转换”,这是不正确的。类型转换与sizeof运算符具有相同的优先级,这意味着在同时使用两者的情况下,它们只是从右到左计算。sizeof(int) * p可能不起作用,因为如果操作数是大括号中的类型,则首先处理,但sizeof((int)*p)工作得很好。
我要求对如何实施
sizeof进行一些技术阐述。这对任何不想传播错误信息、不准确信息的人都有用,或者像我这样 - 从事直接依赖于它的项目。 -
【问题讨论】:
-
您的第二个 sn-p 可以在编译时轻松评估。
*p的类型固定为char,其大小始终为 1。顺便说一句:sizeof运算符的结果是size_t类型,它使用%zu格式说明符打印,而不是 @987654342 @. -
@Gerhardh 是的(关于你的第一句话)我认为这不是正确的例子。
-
关于您的第 (3) 点,这篇文章是正确的:在您的示例
sizeof((int)*p)中,sizeof的操作数不是类型转换;它是((int)*p),即类型转换括号内.这是一个差异,这与sizeof如何解释其参数非常相关。 -
sizeof总是在编译时计算,可变长度数组除外,即使对于c + c,结果也是int:sizeof(c + c) == sizeof(int)而sizeof(3.14 * 2) == sizeof(double) -
对于它的价值,这个问题取决于 IMO,巨大VLA 与 C 中所有其他类型之间的区别。这当然是为什么它们最初不在语言中的原因;我相信这也解释了为什么它们是可选的,并且仍然没有在所有 C 程序员中普遍流行。