1

I am currently writing a simple function in C, which is structured in this way:

int *fillArray(int dim)
{
    static int ar[dim];
    // fill the array ar in some way
    return ar;
}

It is usually said that using the static keyword in local function is discouraged. I was wondering if it was better to do in the classic way:

void fillArray(int *ar, int dim)
{
    // fill the array ar in some way 
}

As a further fact, consider that I later want to wrap the function in Python code, and the Python function should not take parameters.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
aretor
  • 2,379
  • 2
  • 22
  • 38
  • 5
    does your first example compile? I don't see how it can be static _and_ with variable dimension. – Jean-François Fabre Feb 04 '17 at 08:23
  • If you use `static int ar[dim]` there will only ever be one `ar` even if `fillArray` is called multiple times. Are you sure this is what you want? See https://stackoverflow.com/questions/572547/what-does-static-mean-in-a-c-program It also means the two functions act very differently. – Schwern Feb 04 '17 at 08:24
  • Thanks, I am quite disaccustomed to C. So it seems that the second option is mandatory in this case. – aretor Feb 04 '17 at 08:29
  • 1
    Besides that `dim` is missing the type, I doubt this `int* fillArray(dim) { static int ar[dim]; ...` would compile. As far as I know you cannot have a VLA being declared static. How should this work? – alk Feb 04 '17 at 09:56
  • @alk sorry, that was a mistake, I corrected it. – aretor Feb 04 '17 at 11:08
  • 2
    The missing type wasn't my point. This still `int* fillArray(int dim) { static int ar[dim]; ...` won't compile as you cannot have a [Variable Length Array](https://en.wikipedia.org/wiki/Variable-length_array) (which `ar[dim];`defines) being declared as `static`. – alk Feb 04 '17 at 11:34

3 Answers3

1
int *fillArray(dim)
{
    static int ar[dim];
    // fill the array ar in some way
    return ar;
}

Fill array using static does not makes much sense. Every time this function will be called, this will return same array (same address of the static array). Therefore, multiple calls to fillArray which returns a static variable, may in fact corrupt the previous use of the array. Also, you should ideally never return the address of a variable locally defined.

Also, second fillArray function makes much sense, as it can be actually reused.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Chirag
  • 618
  • 6
  • 21
  • 1
    Returning the address of a static variable is OK as long as it meets your multithreading requirements, etc. It's the address of an automatic variable that should never be returned. You might also note that the 'implicit `int`' for `dim` in the argument list was obsolescent in C89/C90 and formally removed from C99. – Jonathan Leffler Feb 04 '17 at 08:39
  • 1
    Please see [my comment on the OP](http://stackoverflow.com/questions/42038148/fill-an-array-in-c-is-it-better-to-create-a-static-local-variable-or-a-passing#comment71251461_42038148). – alk Feb 04 '17 at 09:58
0

As suggested by @alk the first solution does not even compile. Thus the second solution is mandatory, at least for VLA.

aretor
  • 2,379
  • 2
  • 22
  • 38
  • Be aware that with the 2nd solution the function does not receive s pointer to a specific kind of array, but just a pointer to its 1st element. So the function has no idea of the number of array elements to initialisiert. The `sizeof` Operator won't help here as it just gave you the size of the pointer or the element it points to. – alk Feb 04 '17 at 19:27
  • Well, please do not edit the question significantly after comments/answers had been given, as this might render comments/answers ununderstandable. Apply changes by *adding* updates to the question. Please adjust your last change accordingly. – alk Feb 05 '17 at 09:08
0

Your fillArray function is incorrect: the size of an object with static duration must be known at compile time. Furthermore, asa suggested by user3150716, returning the address of a local object with static storage would return the same array every time, which might not be the intent.

You should use a different approach:

  • write a function to allocate a new array
  • use a different function to initialize an array with its size passed as an argument.

Here is an example:

#include <stdlib.h>

int *fillArray(int *array, size_t size) {
    if (array != NULL) {
        for (size_t i = 0; i < size; i++)
            array[i] = 0;
       }
    }
    return array;
}

int *newArray(size_t size) {
    return fillArray(malloc(size * sizeof(int)), size);
}

void freeArray(int *array) {
    free(array);
}

Note that allocating and initializing the array to 0 can be performed in a single step with calloc(size, sizeof(int)).

chqrlie
  • 131,814
  • 10
  • 121
  • 189