简体   繁体   中英

Variably modified type in C language

Can anyone explain what a variably modified type is?

If we have an array a[n] and n is not known at compile time then a is a VLA. Given an array b[c][d] where c and d are not known until runtime implies b is a VLA, right?

In my book they have said that a variably modified type contains a VLA. That's it; nothing more.

How do I create a pointer to a variably modified type?

A variably-modified type is a VLA (variable length array). There's a similar type in a structure with a flexible array member, but I don't plan to discuss flexible array members further.

The key point about a VLA is that the dimension of an array is not known until run-time. Classically, in C89 and before the standard, all dimensions of an array except the first had to be a known constant value at compile time (and the first dimension could be specified as int a[] or int b[][SIZE] or int c[][SIZE1][SIZE2] where the sizes are constants).

void some_function(int n)
{
    int a[n];
    int c = n+1;
    int d = n+2;
    int b[c][d];
    another_function(n, a, c, d, b);
    ...
}

void another_function(int n, int a[n], int c, int d, int b[c][d])
{
    ...
}

Both a and b are variable length arrays. Prior to C99, you could not have written some_function() like that; the size of the arrays would have to be known at compile time as compile-time constants. Similarly, the notation for another_function() would not have been legal before C99.

You could, and still can (for reasons of backwards compatibility, if nothing else) write a moderate simulation of another_function() :

enum { FIXED_SIZE = 32 };

void yet_another_function(int a[], int n, int b[][FIXED_SIZE], int c)
{
    ...
}

This isn't a perfect simulation because the FIXED_SIZE is a fixed size, but the pure C99 VLA code has a variable dimension there. Old code would often, therefore, use a FIXED_SIZE that was large enough for the worst case.

Inside another_function() , the names a and b are basically pointers to variably modified types.

Otherwise, you do it the same as for a fixed size array:

int z[FIXED_SIZE];
int (*z_pointer)[FIXED_SIZE] = &z;

int v[n];
int (*v_pointer)[n] = &v;

VLA == Variable Length Array

Variable Length Arrays were introduced in the C99 spec to allow for things like this:

int someArraySize;
int myArray[someArraySize];

Variably Modified type is the type of a Variable Length Array. Thus, a Variably Modified type CONTAINS a VLA. In the case of your example of b[c][d] where c and d are not known until run time, b is a Variably Modified type that happens to be a Variable Length multi-dimensional array. b[c][d] is a variable length array of variable length arrays-- phew, what a mouthful.

Here is a great source I found that describes these VLAs and the Variably Modified type with examples:

http://gustedt.wordpress.com/2011/01/09/dont-be-afraid-of-variably-modified-types/

VMT is a type usually used to allocate heap blocks of VMT size. The pointer to VMT is not VLA.

#include <stdlib.h>

int main( const int argc, char * const argv[argc])
{
    typedef char * VMT [argc] ;

    VMT * vmt_ptr = malloc(sizeof(VMT));

    * vmt_ptr[0] = argv[0] ;

    free(vmt_ptr);

   return 42;
}

Some people prefer to call them "VLA on the heap". For some people that defeats the purpose of VLAs. For them, VLA is a small(er) array on the stack.

 { // VMT is a type of VLA
   VMT VLA  ;
       VLA[0] = argv[0] ;
 }

No mem leak here. But then some people are wondering what the fuss is all about.

{
    typedef char * VMT [argc] ;

    VMT * vmt_ptr = alloca(sizeof(VMT));

    * vmt_ptr[0] = argv[0] ;
}

They are using alloca, using the VMTs in the process. Effectively creating VMT pointers to blocks allocated on stack space.

There are valid use cases for all three snippets. I hope also showing what are the VMT's.

Mandatory Godbolt: https://godbolt.org/z/zGe4K5hez

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM