1

Let's say I declare a fixed size array and initialize it's members. Is there a way to check at compile time, if all members were initialized, so that I can avoid bugs because of unitialized values? Here's an example I'm working on:

enum image_format {
    IMAGE_FORMAT_UBI = 0,
    IMAGE_FORMAT_BOOT,
    IMAGE_FORMAT_RAW,
    _IMAGE_FORMAT_LAST
};

#define IMAGE_FORMAT_COUNT (_IMAGE_FORMAT_LAST - IMAGE_FORMAT_UBI)

static int image_format_validator_ubi(const char *filename);
static int image_format_validator_boot(const char *filename);

typedef int (*image_format_validator)(const char *filename);

static image_format_validator image_format_validators[IMAGE_FORMAT_COUNT] = {
    [IMAGE_FORMAT_UBI]  = &image_format_validator_ubi,
    [IMAGE_FORMAT_BOOT] = &image_format_validator_boot,
    [IMAGE_FORMAT_RAW]  = NULL
};

In this case, I'd like to check that IMAGE_FORMAT_COUNT amount of elements were initialized inside the image_format_validators array.

PoVa
  • 995
  • 9
  • 24
  • 1
    Note that if you have an automatic array without an initializer, or a dynamically allocated array allocated with `malloc()`, or a variable length array (necessarily without an initializer — you can't initialize a VLA), then the contents of the array are indeterminate (but you can be sure that every element was not intialized). Your code shows static arrays; those are always fully initialized (either explicitly or with the default — zero — initializer). Arrays allocated with `calloc()` are initialized with all bytes zero. Extra memory allocated with `realloc()` is not initialized. – Jonathan Leffler Sep 21 '18 at 04:15

1 Answers1

1

Is there a way to check at compile time, if all members were initialized (?)

There is no partial initialization in C it is all or nothing. Elements not explicitly initialized will get initialized with a default value.


To help detect if image_format_validators[] is the expected size, one approach uses a _Static_assert(constant-expression , string-literal). If the constant-expression is unequal to 0, all is well. Else "the implementation shall produce a diagnostic message that includes the text of the string literal" C11 §6.7.10 3

enum image_format {
    IMAGE_FORMAT_UBI = 0,
    IMAGE_FORMAT_BOOT,
    IMAGE_FORMAT_RAW,
    IMAGE_FORMAT_N
};

//                                                    v--- empty
static image_format_validator image_format_validators[ ] = {
    [IMAGE_FORMAT_UBI]  = &image_format_validator_ubi,
    [IMAGE_FORMAT_BOOT] = &image_format_validator_boot,
    [IMAGE_FORMAT_RAW]  = NULL
};

#define IFV_N (sizeof image_format_validators/sizeof image_format_validators[0])
_Static_assert(IFV_N == IMAGE_FORMAT_N, "Unexpected size");

The above can still get fooled, but does work well to insure a sequential enumerated type mapped to an array has the expected N array elements.


If not using C11, see the compile time check alternative: C_ASSERT(expr).

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256