As said above.
Your declaration actually doesn't make much sense either. How do you think you're going to actually use the elements which are themselves arrays?
I suppose you were expecting to use zero as a sentinel value for showing the end of the list for each inner array?
Guessing - you were maybe expecting:
- the compiler to figure out the maximum number of items required for the "inner" arrays (in your example, that would be 3);
- the compiler to automatically initialize the inner arrays with zero for the missing items in initializers;
- the compiler to be able to give you the size of the inner arrays with something like sizeof(TCAn_output_pin_enable[0]).
This isn't going to happen. C is not that "smart".
Here the solution is just to give the inner arrays a maximum fixed size. Then the 3 points above will work.
Pick a max size for the inner arrays - for instance 8:
uint8_t TCAn_output_pin_enable[] [8] = {{0}, { TCA0_waveform_output_0_enable, TCA0_waveform_output_1_enable, TCA0_waveform_output_2_enable }} ;
A better approach IMO would be to define a type for the "inner arrays", which are lists of flags as far as I can tell. This type could be an array of uint8_t (which will have to have a fixed size), or a pointer to uint8_t, if you want more efficient use of memory (but saving just a few bytes here is probably not worth it.) Much easier to read than multi-dimensional arrays, and then you can write functions taking the lists as a parameter.
enum ConfigKey {
ConfigKey_a,
ConfigKey_c,
ConfigKey_b,
// …
ConfigKey_n
};
enum {
Mask_out1Enable = 1 << 0,
Mask_out2Enable = 1 << 1,
Mask_out3Enable = 1 << 2
// …
};
static unsigned char const config[ConfigKey_n] = {
[ConfigKey_a] = 0,
[ConfigKey_b] = Mask_out1Enable | Mask_out2Enable | Mask_out3Enable,
[ConfigKey_c] = Mask_out1Enable
};
void initialize(enum ConfigKey const key) {
if (key < 0 || key >= ConfigKey_n) {
// Handle error
}
if (config[key] & Mask_out1Enable) {
// enable output #1
}
if (config[key] & Mask_out2Enable) {
// enable output #2
}
if (config[key] & Mask_out3Enable) {
// enable output #3
}
// …
}
Explicit size and the indexes in the initializer are there to prevent silly mistakes. With that syntax it is more likely that, if you make an error, either the compiler will scream at you or at least no garbage will be set by the setup function. However, you may skip the ConfigKey part and then you will have automatically sized, yet less safe, array.