2023-01-03

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 (malloc, etc)
  • can be accessed in subfunctions
  • can not be accessed after the declaring function has returned
  • if the array is part of a struct, struct and array have to be declared separately
  • #include could be used to keep large definitions in a separate file and include the definitions where needed
  • type names like int[4][2] have to be used for variables and functions, and only this exact format can be passed

this method can also be used to define nested arrays:

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

option: functions as literal array expressions

int* ints4(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 = ints4(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 = ints4(1, 2, 3, 4);
if (!x) goto exit;

option: macro that sets values

  • array must have been declared and allocated separately
  • it is not an expression that returns an array pointer in place
#define int4(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);
ints4(x, 2, 3, 4, 5);