gpt4 book ai didi

c - 在 C99 中如何在运行时计算可变长度数组的大小?

转载 作者:太空狗 更新时间:2023-10-29 16:44:32 25 4
gpt4 key购买 nike

在 C89 中,数组的长度在编译时已知。但在 C99 中,对于可变长度数组,数组的长度在运行前可能是未知的。

那么它是如何计算出来的呢?

为什么不能以相同的方式计算动态分配的数组的长度?

最佳答案

摘自 ISO/IEC 9899:TC3 第 6.7.5.2 节:数组声明符

An ordinary identifier (as defined in 6.2.3) that has a variably modified type shall have either block scope and no linkage or function prototype scope. If an identifier is declared to be an object with static storage duration, it shall not have a variable length array type.

VLA 的大小就是sizeof(vla_element_type) * vla_length。由于 VLA 只能在 block 内定义,它的长度必须是局部变量或函数参数,在访问 vla 时编译器可以访问它。 (因为vla的长度和vla本身属于同一个栈帧)。

Here is an example:

int main(int argc, char* argv[])
{
int m;
scanf("%d\n", &m);
int a[m];

printf("%d\n", sizeof(a));

return 0;
}

clang -o test.ll -O2 -emit-llvm -S test.c编译,生成的IR如下所示:

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
entry:
// Allocate space on stack for m
%m = alloca i32, align 4

// call scanf
%call = call i32 (i8*, ...)* @__isoc99_scanf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %m) nounwind

// %0 now contains the value of m
%0 = load i32* %m, align 4, !tbaa !0

// %1 is m << 2, which is m * sizeof(int)
%1 = shl nuw i32 %0, 2

// call printf, output m * sizeof(int) to screen.
%call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %1) nounwind

// DONE.
ret i32 0
}

关于c - 在 C99 中如何在运行时计算可变长度数组的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13908421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com