4

Is it possible to have a compile-time check on array values?

example:

typedef enum
{
    dummy0 = 0,
    dummy1,
    dummy2
} eDummyEnum;

typedef struct
{
    eDummyEnum name;
    int value;
} sDummyStruct;

const sDummyStruct array[]=
{
    {dummy0, 3},
    {dummy1, 5},
    {dummy2, 6}
}

Is there any possibility to check if array[dummy1].name == dummy1 at compilation time?

10
  • You don't need to check it. You wrote it right there in the initialising code. Commented Nov 29, 2015 at 18:54
  • array is big, and there is a chance to write {dummy0, 3}, {dummy2, 5}, {dummy1, 6}
    – Mihai
    Commented Nov 29, 2015 at 18:58
  • 1
    no, because what i want to test is that the array initialization is in the same order as the enum
    – Mihai
    Commented Nov 29, 2015 at 19:03
  • 1
    @LightnessRacesinOrbit: Absolute nonsense. If there's a 10% chance of error in one list, then having two lists drops the chance of error down to 1%. This is exactly why we have automated tests. Commented Nov 29, 2015 at 19:31
  • 1
    If I cannot find a way to avoid such self-repeating code, I prefer to generate it with a small script. It will be easier to maintain that way.
    – 5gon12eder
    Commented Nov 29, 2015 at 19:35

2 Answers 2

4

Something along these lines, perhaps:

constexpr sDummyStruct array[]=
{
    {dummy0, 3},
    {dummy1, 5},
    {dummy2, 6}
};

constexpr bool checkArray(int index) {
    return (index >= sizeof(array)/sizeof(array[0])) ||
           (array[index].name == index && checkArray(index + 1));          
}

static_assert(checkArray(0), "bad array");

Live demo

0
0

I guess, this could be made a bit more efficient but I think the following code does work correctly:

template <typename T, int N>
constexpr int size(T(&)[N]) {
    return N;
}

template <int I, int J>
struct check_name {
    static constexpr bool check() {
        return array[I].name != array[J].name
            && check_name<I + 1, J>::check()
            && check_name<I, J - 1>::check();
    }
};

template <int I>
struct check_name<I, I> {
    static constexpr bool check() { return true; }
};
constexpr bool check_names() {
    return check_name<0, size(array) - 1>::check();
}

static_assert(check_names(), "duplicate names");
1
  • it does work correctly but as far as i've seen it doesn't check the order of the initialization list, only duplicate names, but thanks
    – Mihai
    Commented Nov 29, 2015 at 20:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.