Search code examples
carraysvariable-length-array

Prototype for variable-length arrays


I am trying to write a function that takes an array of an variable size in c.

void sort(int s, int e, int arr[*]){
    ...
}

It says that for variable length arrays, it needs to be bounded in the function declaration. What does that mean? I am using xcode 4.0, with the LLVM compiler 2.0.

Thanks for the help.


Solution

  • If you're not using the C99 variable length arrays (it appears you are, so see below), the usual solution is to pass in a pointer to the first element, along with any indexes you want to use for accessing the elements.

    Here's a piece of code that prints out a range of an array, similar to what you're trying to do with your sort.

    #include <stdio.h>
    
    static void fn (int *arr, size_t start, size_t end) {
        size_t idx;
        for (idx = start; idx <= end; idx++) {
            printf ("%d ", arr[idx]);
        }
        putchar ('\n');
    }
    
    int main (void) {
        int my_array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
        fn (my_array, 4, 6);
        return 0;
    }
    

    This outputs elements four through six inclusive (zero-based), giving:

    5 4 3
    

    A couple of points to note.

    • Using my_array in that function call to fn automatically "decays" the array into a pointer to its first element. This actually happens under most (not all) circumstances when you use arrays, so you don't have to explicitly state &(my_array[0]).

    • C already has a very good sort function built in to the standard library, called qsort. In many cases, that's what you should be using (unless either you have a specific algorithm you want to use for sorting, or you're doing a homework/self-education exercise).


    If you are using real VLAs, you should be aware that the [*] construct is only valid in the function prototype, not in an actual definition of the function.

    So, while:

    void xyzzy(int, int[*]);
    

    is valid, the following is not:

    void xyzzy(int sz, int plugh[*]) { doSomething(); }
    

    That's because, while you don't need the size parameter in the prototype, you do very much need it in the definition. And, since you have it, you should just use it:

    void xyzzy(int sz, int plugh[sz]) { doSomething(); }
    

    The gcc compiler actually has a reasonably clear error message for this, far better than the "needs to be bounded in the function declaration" one you saw:

    error: ‘[*]’ not allowed in other than function prototype scope