gpt4 book ai didi

c - 一致的数组参数是 VLA 吗?

转载 作者:太空宇宙 更新时间:2023-11-04 03:17:38 29 4
gpt4 key购买 nike

CERT's Secure Coding Standard包括一项 ( API05-C ),它鼓励使用一致的数组参数,这是我在很多代码中实现的建议(对于不支持它们的编译器,隐藏在 a macro 后面)。

对于那些不知道的人,一致的数组参数是这样的:

void foo(int length, char data[length]);

API05-C提供更多信息。

许多编译器不喜欢可变长度数组(有充分的理由)。 C11 将它们从必需(就像在 C99 中一样)降级为可选(如果未实现,编译器应定义 __STDC_NO_VLA__)。 MSVC 完全不支持它们。 IAR 将它们隐藏在一个开关后面 (--vla)。如果您询问(使用 -Wvla,或者如果您想要错误,则使用 -Werror=vla),GCC 和 clang 会警告您。

一致的数组参数不会遇到与“普通”可变长度数组相同的问题;它们不会导致变量堆栈的使用。它们只是告诉编译器现有数组有多大(可能位于堆栈或堆上)。

我的问题是,我所知道的每个编译器都将一致的数组参数视为 VLA。对于像 MSVC 这样的编译器来说这不是什么大问题,因为我可以将我的宏定义为空,但是对于像 GCC 和 clang 这样的编译器我想使用一致的数组参数但不想触发 -Wvla诊断。

根据 API05-C(添加了重点):

Consequently, an array declaration that serves as a function argument may have an index that is a variable or an expression. The array argument is demoted to a pointer and is consequently not a variable length array (VLA). Conformant array parameters can be used by developers to indicate the expected bounds of the array. This information may be used by compilers, or it may be ignored. However, such declarations are useful to developers because they serve to document relationships between array sizes and pointers. This information can also be used by static analysis tools to diagnose potential defects.

我非常希望这是真的,但我似乎找不到 C99 的相关部分或 C11标准。

那么,严格基于 C99/C11 标准,一致的数组参数是否为 VLA?或者,换句话说,将数组作为参数传递真的会将其降级为指针吗?

显然,请引用规范的相关部分。

最佳答案

所有声明为数组类型的参数都被转换为指针类型。 VLA 也不异常(exception)。

N1256(C99+TC1+TC2+TC3):

6.7.5.3 Function declarators (including prototypes)

7 A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

声明为 void f(int a[10]); 的函数采用任何 int *。声明为 void f(int length, int array[length]); 的函数采用 intint *

但是,你写:

My issue is that every compiler I'm aware of treats conformant array parameters as VLAs. This isn't such a big deal for compilers like MSVC since I can just define my macro to nothing, but for compilers like GCC and clang I want to use conformant array parameters but don't want to trigger -Wvla diagnostics.

嗯,这很棘手。在转换为指针之前,它一个 VLA,-Wvla 的目的是警告在不支持 VLA 的编译器上无法编译的代码。如您所见,MSVC 不喜欢该代码。

Conformant array parameters don't suffer from the same problems as "normal" variable-length arrays; they don't result in variable stack usage. They just tell the compiler how big an existing array, which could be on the stack or heap, is.

不,他们不会那样做。给定 void f(int a[10]);,使用空指针、指向长度为 1 的数组的指针等调用 f 是完全有效的。编译器必须支持它。它们仅作为对人类读者的提示。这同样适用于转换后的 VLA。

关于c - 一致的数组参数是 VLA 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49962479/

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