Are conformant array parameters VLAs?

江枫思渺然 提交于 2019-12-24 10:39:41

问题


CERT's Secure Coding Standard includes an item (API05-C) which encourages the use of conformant array parameters, which is a recommendation I've implemented in a lot of my code (hidden behind a macro for compilers which don't support them).

For those who don't know, a conformant array parameter is something like:

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

API05-C provides more information.

Lots of compilers don't like variable-length arrays (for good reason). C11 demotes them from required (as they were in C99) to optional (compilers should define __STDC_NO_VLA__ if they're not implemented). MSVC flat out doesn't support them. IAR hides them behind a switch (--vla). GCC and clang will warn you about them if you ask (with -Wvla, or -Werror=vla if you want an error).

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.

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.

According to API05-C (emphasis added):

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.

I desperately want this to be true, but I can't seem to find the relevant parts of the C99 or C11 standards.

So, based strictly on the C99/C11 standards, are conformant array parameters VLAs? Or, to put it another way, does passing an array as an argument really demote it to a pointer?

Obviously, please cite the relevant parts of the specification(s).


回答1:


All parameters declared as array types are transformed to pointer types. VLAs are no 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.

A function declared void f(int a[10]); takes any int *. A function declared void f(int length, int array[length]); takes an int and a int *.

However, you write:

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.

Well, it's tricky. It is a VLA before it is transformed to a pointer, and the point of -Wvla was to warn about code that would fail to compile on compilers that do not support VLAs. As you've seen, MSVC doesn't like the code.

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.

No, they do not do that. Given void f(int a[10]);, it is perfectly valid to call f with a null pointer, with a pointer to an array of length 1, etc. The compiler must support that. They only serve as a hint to human readers. The same applies to transformed VLAs.




回答2:


They are not VLA, but just pointers. If you extend that rule to more than one dimension you obtain a variably modified type, VM, still not a VLA.

If you want to indicate that the pointer should not be 0, there is static as in

void Toto(size_t n, double vec [static n]);

which indicates that vec must have at least n elements, and in particular can't be null.



来源:https://stackoverflow.com/questions/49962479/are-conformant-array-parameters-vlas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!