Reputation: 1240
Would it be a good practice to use the following preprocessor trick in a code with full of vector calculations? On the one hand it pollutes the namespace using generic identifiers (mul,add,...) and smells like a dirty hack, but on the other hand it may makes complex expressions more readable. Are there any other pros/cons?
typedef struct { double x,y; } vector;
vector vector_add(vector v0, vector v1);
double vector_mul(vector v0, vector v1);
...
#define _(a) opf(a)
#define mul ,mul,
#define add ,add,
...
#define opf(a,o,b) vector_##o((a),(b))
void example(void)
{
vector a, b, c;
double d;
d = _( _(a add b) mul c);
// equivalent without the macros:
d = vector_mul(vector_add(a,b),c);
}
Upvotes: 3
Views: 940
Reputation: 263497
No, it's not a good idea (in my opinion, of course).
Assuming I know the C language reasonably well, if I see a line of code like:
d = vector_mul(vector_add(a,b),c);
I have a pretty good idea what it does. I need to look at the types of a
, b
, c
, and d
, and the declarations of the functions, to be sure, but even without that I can safely assume it's doing a vector addition and a vector multiplication.
On the other hand, if I see:
d = _( _(a add b) mul c);
I'll likely have no clue what it's doing until I first track down the macro definitions, and then either study them until I understand your new syntax, or just expand them myself to ordinary C code that I can understand. Of course you know what your syntax means, and that's fine if you're the only person reading the code, but anyone else will wonder what the underscores are for.
And that's assuming I realize that you're using macros. Macro names are conventionally written in all-caps. Using ADD
and MUL
would be an improvement, but IMHO not enough to override the other disadvantages.
A personal anecdote: Many years ago, when I was first learning C, I thought that this:
#define EVER ;;
...
for (EVER) {
/* ... */
}
was very clever. I still think it's very clever; I just no longer think it's a good idea.
Upvotes: 3