In my C application I configure some features in this way:
#define LED_SIZE 113
#define SEGMENT_SIZE 3
const int LED_SEGMENTS[SEGMENT_SIZE] = {30, 70, 13};
I would like to check if the sum of the literal values are equal to LED_SIZE
:
30 70 13 = 113
I'm interested to do this at compile time, using a pre-processor directives. If the sum is not correct it should not compile.
CodePudding user response:
you can use static_assert
#define LED_SIZE 113
#define SEGMENT_SIZE 3
constexpr int LED_SEGMENTS[SEGMENT_SIZE] = {30, 70, 13}; // this need to be constexpr
#include <numeric>
static_assert(
std::accumulate(LED_SEGMENTS,LED_SEGMENTS SEGMENT_SIZE,0) == LED_SIZE
);
note: std::accumulate
is constexpr
only since c 20, you may need to write a custom one for earlier standard.
CodePudding user response:
Avoid the C pre-processor.
#include <array>
#include <numeric>
constexpr int LED_SIZE = 113;
constexpr int SEGMENT_SIZE = 3;
constexpr std::array<int, SEGMENT_SIZE> values{30, 70, 13};
static_assert(std::accumulate(values.begin(), values.end(), 0) == LED_SIZE);
CodePudding user response:
using a pre-processor directives
It is not possible to access arrays using preprocessor directives. LED_SEGMENTS[0]
means literally LED_SEGMENTS[0]
for preprocessor, there is no array access in preprocessor.
You could stay with it in preprocessor world, and then write a variadic overloaded argument macro to calculate the sum of the comma separated list:
#define LED_SIZE 113
#define SEGMENT_SIZE 3
#define LED_SEGMENTS 30, 70, 13
#define SUM_1(a) a
#define SUM_2(a, ...) a SUM_1(__VA_ARGS__)
#define SUM_3(a, ...) a SUM_2(__VA_ARGS__)
#define SUM_4(a, ...) a SUM_3(__VA_ARGS__)
#define SUM_N(_4,_3,_2,_1,N,...) SUM##N
#define SUM_IN(...) SUM_N(__VA_ARGS__,_4,_3,_2,_1)(__VA_ARGS__)
#define SUM(...) SUM_IN(__VA_ARGS__)
#if SUM(LED_SEGMENTS) != LED_SIZE
#error "SUM(LED_SEGMENTS) != LED_SIZE"
#endif
to do this at compile time
You should use:
#include <functional>
#include <numeric>
#define LED_SIZE 113
#define SEGMENT_SIZE 3
constexpr int LED_SEGMENTS[SEGMENT_SIZE] = {30, 70, 13};
static_assert(std::accumulate(std::begin(LED_SEGMENTS), std::end(LED_SEGMENTS), 0) == LED_SIZE);
CodePudding user response:
You can use the #if
preprocessor directive:
#define LED_SIZE 113
#define SEGMENT_SIZE 3
const int LED_SEGMENTS[SEGMENT_SIZE] = {30, 70, 13};
#if (LED_SEGMENTS[0] LED_SEGMENTS[1] LED_SEGMENTS[2] != LED_SIZE)
#error "sum of LED segments is not equal the total LED size"
#endif
(untested)