It could be well approximated in standard C by embedding struct adc_cfg in a a union where the other member will be the an array of struct adc_pin of a fixed size.
#include <stdio.h>
#include <stddef.h>
struct adc_pin {
int pin;
int channel;
};
struct adc_cfg {
int pin_count;
struct adc_pin pins[];
};
#define PINS_CFG {{0,1}, {2,3}}
#define PINS_COUNT(PIN_CFG) sizeof (struct adc_pin[]) PINS_CFG / sizeof (struct adc_pin)
const union adc_cfg_ {
struct adc_cfg cfg;
struct {
int pin_count;
struct adc_pin pins[PINS_COUNT(PINS_CFG)];
};
} adc_cfg_ = {
.cfg.pin_count = PINS_COUNT(PINS_CFG),
.pins = PINS_CFG,
};
_Static_assert(offsetof(union adc_cfg_, cfg.pins) == offsetof(union adc_cfg_, pins), "oops");
#define adc1 (adc_cfg_.cfg)
int main() {
printf("%d %d\n", adc1.pins[0].pin, adc1.pins[0].channel);
printf("%d %d\n", adc1.pins[1].pin, adc1.pins[1].channel);
}
The program prints the expected output of
0 1
2 3
The trick is that the arrays adc_cfg_.cfg.pins and adc_cfg_.pins alias because they are placed in the same union at the same position.
From definition of flexible array member 6.7.2.1p18:
it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed
The object is the whole union so the flexible member should behave like an array of two elements.
Theoretically, this solution is not-full portable because the offset of pins in the anonymous union does not have to the same as offset within the object. However, it is very unlikely and it can be easily checked with _Static_assert as in the code snippet.
Moreover the rule 6.5.2.3p6 about the common initial sequence suggests that the code will work in all cases and be portable.
The size of the pins array is computed using a compound literal. For example an initializer {1,2,3} can be transformed into an anonymous array with expression (int[]){1,2,3}. This array can be used with a traditional method of deriving the count of array as sizeof <array> / sizeof array-element.
EDIT.
GPIO_TypeDef, so other people cannot readily compile it. The specific types are not needed for this question; you could easily replace the types of the members ofadc_pinwithint, as I have done in my answer.a b chave less meaning for many of us than physical quantities, even if it isn't directly copy-pasta'able. However, I see your point as well and as you're the one doing me the favor of trying to answer my question I figure I can certainly defer to you on this.