c - 为什么 C 允许对尚未创建的变量使用 sizeof 运算符?
问题描述
考虑以下示例代码:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(sizeof *a);
*a = 5;
free(a);
return 0;
}
在本例中,我在堆上分配整数a
并将其初始化为 5。这一行具体
int *a = malloc(sizeof *a);
是什么让我感到困惑(sizeof *a
部分)。对我来说,这看起来像是我试图在变量创建之前获取它的大小,但我发现这种初始化指针的方式非常普遍。当我用 clang 编译这段代码时,我没有收到任何错误或警告。为什么编译器允许这样做?据我所知,这类似于做类似的事情
int a = a + 1;
没有任何先前的声明a
。这会产生警告clang -Wall main.c
:
main.c:17:13: warning: variable 'a' is uninitialized when used
within its own initialization [-Wuninitialized]
int a = a + 1;
是什么让这一行与指针声明不同sizeof
?
解决方案
除非它是可变长度数组,否则不会sizeof
计算运算符的操作数。仅查看它以确定其类型。
此行为记录在C 标准的第 6.5.3.4p2 节中:
运算符产生其
sizeof
操作数的大小(以字节为单位),它可以是表达式或带括号的类型名称。大小由操作数的类型决定。结果是一个整数。 如果操作数的类型是变长数组类型,则计算操作数;否则,不计算操作数,结果是一个整数常量。
在这种情况下,它知道*a
有 类型int
,因此*a
不求值并且sizeof *a
与 相同sizeof(int)
。
推荐阅读
- javascript - 导入的 JS 文件 - 错误 - [JSC_UNDEFINED_VARIABLE] 变量分页未声明
- visual-studio - 在 Visual Studio 2017 的 launchSettings.json 中手动定义端口
- reactphp - 在 PHP 主机上部署 ReactPHP
- javascript - 如何在 php 中向另一列输入值(如借记卡和贷记卡)时自动将一列设置为 0?
- jquery - 带有 Tabledit jquery 的数据表
- hibernate - CrudRepository 方法的 Transactional 注释
- json - 当我有 JSON / OBJ / JSON / OBJ / JSON 时显示 product.length
- bash - 如何报告多程序脚本的退出代码?
- kubernetes - Openshift 模板能否在多个项目上创建对象
- sql - T-SQL 仅在不存在时选择行