Reputation: 176
I have a function that looks like this:
int div_round_up(int x, int y) {
/**
* This function only works for positive divisor and non-negative dividend!!
*/
assert(y > 0 && x >= 0);
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
It won't work with y <= 0
or x < 0
. That's ok with me, I can even dynamically check for right values, but I would like to check statically, when someone feeds it wrong values. If I defined x and y as unsigned, they would get silently converted from negative values to huge positive values which would produce erroneous result, so I don't want that. I would like to make compilation fail when someone attempts to feed it negative values like in div_round_up(variable, -7)
. What should I do?
Upvotes: 3
Views: 226
Reputation: 395
Yeap you can do it with some magic(one nonamed russian code guru told me this trick)
#define check2(x) typedef char checkVal[(x)?1:-1];
int main() {
check2(3<4);
check2(5<4);
return 0;
}
but also in this case there is one limit. Compiler should know result of this value. In any another case it`s imossible(IMHO).
Upvotes: 0
Reputation: 24926
If you're using gcc or clang you can include a macro
#define div_round_up(a, b) (__builtin_constant_p(b) ? drus(a, b) : drud(a, b))
and two different function where drus
includes a static assertion for b while drud
does not.
Upvotes: 2
Reputation: 11116
To verify a number at compile time (which is what static_assert
does), it has to be known at compile time. To see why this is needed, consider that something like div_round_up(read_integer_from_file(), read_keyboard_character())
. The obvious drawback of doing that is that you have to know the numbers at compile time.
The easiest way is to make them template parameters, which allows you to leave the implementation of the function (almost) the same:
template<int x, int y>
int div_round_up() {
static_assert(y > 0 && x >= 0, "This function only works for positive divisor and non-negative dividend");
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
It can be called as div_round_up<3, 4>()
and will fail the compilation when the static_assert
fires.
Upvotes: 3