为什么 C 允许对尚未创建的变量使用 sizeof 运算符?
Why does C allow the sizeof operator on a variable that hasn't yet been created?
考虑以下示例代码:
#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 standard 的第 6.5.3.4p2 节中:
The sizeof
operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
在这种情况下,它知道 *a
的类型为 int
,因此 *a
不被求值并且 sizeof *a
与 sizeof(int)
相同。
在大多数情况下,sizeof
是一个 编译时 运算符。编译器只知道您传递给它的类型的大小。
其次,其实在malloc
调用的时候,变量a
其实已经被定义了。变量在初始化之前必须已经定义(和分配)。否则初始化值会写到哪里?
的问题
int a = a + 1;
不是说a
不存在,而是你在[=16=中使用a
的值是不确定的 ].
对于某些类型,不确定值可能包含 trap representation, and if that happens it leads to undefined behavior.
关于 sizeof
运算符的小提示:编译器本身在编译时评估的唯一一次 不是 是 variable-length arrays。
考虑以下示例代码:
#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 standard 的第 6.5.3.4p2 节中:
The
sizeof
operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
在这种情况下,它知道 *a
的类型为 int
,因此 *a
不被求值并且 sizeof *a
与 sizeof(int)
相同。
在大多数情况下,sizeof
是一个 编译时 运算符。编译器只知道您传递给它的类型的大小。
其次,其实在malloc
调用的时候,变量a
其实已经被定义了。变量在初始化之前必须已经定义(和分配)。否则初始化值会写到哪里?
的问题
int a = a + 1;
不是说a
不存在,而是你在[=16=中使用a
的值是不确定的 ].
对于某些类型,不确定值可能包含 trap representation, and if that happens it leads to undefined behavior.
关于 sizeof
运算符的小提示:编译器本身在编译时评估的唯一一次 不是 是 variable-length arrays。