Reputation: 11268
If I have two integer values I can test for equality simply:
if (a == b)
if I have three integer values then I could do something like:
if ((a == b) && (a == c) && (b == c))
I've got a situation where I've got 6 values to test for equality, this approach is going to get verbose
Is their a better, and more C idiomatic (c-onic?) means to achieve this?
actually, just having written this I can see that:
if ((a == b) && (b == c) && (c == d)... )
is logically ok, i.e. you don't need all the combinations as a == b
and b == c
implies a == c
But in terms of clarity of expression how close can I get to:
if (a == b == c)
?
Upvotes: 6
Views: 194
Reputation: 249552
I can show you how to do it in a variadic macro, so we can write this:
if(EQI(a, b, c, d, e, f))
Here's the code:
#include <stdarg.h>
#include <stddef.h>
#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
#define EQI(...) ( \
alleqi(NUMARGS(__VA_ARGS__), __VA_ARGS__))
/* takes count number of int arguments */
int alleqi(size_t count, ...)
{
va_list va;
va_start(va, count);
int v0 = va_arg(va, int);
for (; count > 1; count--) {
if (v0 != va_arg(va, int)) {
break;
}
}
va_end(va);
return count == 1;
}
Please be advised the above only works for int
arguments (and probably other types whose size is the same as int
, though I am bracing for someone to accuse me of promoting undefined behavior if I advertise that!).
Thanks to this prior post for figuring out how to count arguments in a variadic macro: https://stackoverflow.com/a/2124433/4323
Upvotes: 7
Reputation:
You're not going to get very close to a == b == c
.
To cause experienced C programmers the least surprise, I think this is best is
if(a == b && b == c && c == d && d == e && e == f)
i.e. basically like what you have already, with less parentheses. I'm not always opposed to adding parentheses that make no difference to the compiler to help humans who don't know all the precedence rules, but I think comparisons separated by &&
(with no ||
mixed in) are a simple enough case that the parentheses are more clutter than they're worth.
If the variable names are long, putting it all on one line isn't going to be pretty, so maybe
if(a == b &&
b == c &&
c == d &&
d == e &&
e == f)
or this might be better since the duplication of the the a
in every line will be immediately noticeable:
if(a == b &&
a == c &&
a == d &&
a == e &&
a == f)
If you really want it to be compact, the p99 preprocessor library offers this:
#include "p99_for.h"
if(P99_ARE_EQ(a,b,c,d,e,f))
which looks like John Zwinck's answer but doesn't require a helper function.
Upvotes: 7
Reputation: 25286
Approaches using arrays require you to change your data structure into an array.
Approaches using a variadic macro requires an additional function and function call (overhead).
Except for these two approaches, the only other way I see is to write them out. I feel the best way, or the more clear way, is to take the first variable and compare it to all other variables. By implication then either all variabes are equal, or at least two variables are unequal:
if ((a == b) && (a == c) && (a == d)
&& (a == e) && (a == f) && (a == g) ...)
Upvotes: 2
Reputation: 8614
If you want to check six values, one approach would be to store them in an array
int a[6];
equals = 1;
for (int i=0; i<5; i++)
{
if (a[i] != a[i+1])
{
equals = 0;
break;
}
}
Upvotes: 6