2023-03-28

array literals in c

part of c programming

sometimes it would be useful to assign array content literally by listing the contents. something like this is possible in most scripting languages:

a = [1, 2, 3, 4]

but c is limited and the following shows some possible options and alternatives.

option: on-stack arrays with literal initializer

example:

int a[3] = {1, 2, 3};
  • can only be done once where a variable is defined
  • can only be done for stack arrays, not for heap arrays (allocated by malloc, etc)
  • can be accessed in sub-functions
  • can not be accessed after the declaring function has returned
  • type names like int[4][2] have to be used for all variables and functions that use the type, and only this exact format and number combination can be passed without type casting
  • #include could be used to keep large definitions in a separate file and include the definitions where needed

this method can also be used to define nested arrays:

int a[3][2] = {{1, 2}, {3, 4}, {5, 6}};

additional information:

option: functions as literal array expressions

int* int_array4(int a, int b, int c, int d) {
  int* x = malloc(4 * sizeof(int));
  if (!x) return 0;
  x[0] = a;
  x[1] = b;
  x[2] = c;
  x[3] = d;
  return x;
}
int* e = int_array4(2, 3, 4, 5);

memory allocation can fail, therefore the question of how to handle this failure arises.

option: return a null pointer

this interface is similar to malloc, which also just returns a null pointer on failure.

option: exit the program

no error checking code is needed, or possible, with this option. it does not compose well because it exits the process that uses it, which tends to be particularly undesirable when the code is used as part of a library. inside the array creating function:

if (!x) exit(1);

option: macro that checks the result and uses goto

needs a temporary variable and a local goto label

int* x = int_array4(1, 2, 3, 4);
if (!x) goto exit;

option: macro that sets values

  • array must have been declared and allocated separately
  • is not an expression that returns an array pointer in place
  • same macro can be used for multiple types (int, unsigned int, float, etc)
#define array_set4(x, a, b, c, d) x[0] = a; x[1] = b; x[2] = c; x[3] = d;
int* x = malloc(4 * sizeof(int));
if (!x) exit(1);
array_set4(x, 2, 3, 4, 5);