可变修改类型仅是 VLA 吗?

Is variably-modified type a VLA only?

一个简单的问题:可变修改类型是VLA(可变长度数组)只有吗?

C11, 6.10.8.3 条件特征宏,1(强调已加):

__STDC_NO_VLA__ The integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably modified types.

这是否意味着除了 VLA 之外还有一个可变修改类型?有例子吗?

“可变修饰类型”和“可变长度数组”有什么关系?


额外:“变长数组”的定义依赖于“已知常量大小”的定义:

If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

但是,“已知常数大小”的定义取决于“可变长度数组”的定义:

A type has known constant size if the type is not incomplete and is not a variable length array type.

有点迷糊。

相关 DR:http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_312.htm

Does it mean that there is a variably-modified type, other than VLA? Any examples?

根据 C 标准(6.7.6 声明符)

3 A full declarator is a declarator that is not part of another declarator. If, in the nested sequence of declarators in a full declarator, there is a declarator specifying a variable length array type, the type specified by the full declarator is said to be variably modified. Furthermore, any type derived by declarator type derivation from a variably modified type is itself variably modified.

这是一个演示程序

#include <stdio.h>

int main( void )
{
    for ( size_t n = 1; n < 10; n++ )
    {
        typedef int ( *Ptr )[n];
        Ptr p;

        printf( "sizeof( *p ) = %zu\n", sizeof( *p ) );
    }
}

程序输出为

sizeof( *p ) = 4
sizeof( *p ) = 8
sizeof( *p ) = 12
sizeof( *p ) = 16
sizeof( *p ) = 20
sizeof( *p ) = 24
sizeof( *p ) = 28
sizeof( *p ) = 32
sizeof( *p ) = 36

在此程序中,指针类型 Ptr 定义为 int( * )[n] 是可变修改类型。

这句话

A type has known constant size if the type is not incomplete and is not a variable length array type.

表示此类类型的 sizeof 运算符在 compile-time 处求值,与在 run-time 处对可变长度数组类型的求值相反,并且此类类型的大小未更改在程序执行期间。

引用与下面的引用有不同的含义

If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

说明了如何区分可变长度数组的声明和 non-variable 长度数组的声明。

C 2018 6.7.6 3 说:

If, in the nested sequence of declarators in a full declarator, there is a declarator specifying a variable length array type, the type specified by the full declarator is said to be variably modified. Furthermore, any type derived by declarator type derivation from a variably modified type is itself variably modified.

因此int (*)[n],对于某些non-constantn来说,是一个可变修改类型,即使它是一个指针。此外,int [3][n] 是可变修改类型。