What I've been doing is using a #define UNC
(uncertainty) to toggle on and off the functionality for calculating x
(the value) and dx
(the uncertainty). It works pretty well, but it's not easy to read or write. is there a better way to do this? In C++ I might use std::pair
, or maybe some sort of tuple. I could also use a struct with both x
and dx
, and sometimes leave dx
undefined, but I plan on running this code at very large scales and don't want it slowing down the compiler by processing all these unnecessary items once UNC
is turned off.
Have any of you come across a similar problem?
Here's the code, for reference:
#include <stdio.h>
#define UNC
typedef struct{
double x;
#ifdef UNC
double dx;
#endif
} Foo;
int force(Foo* m, Foo* a, Foo* f){
f->x = m->x * a->x;
#ifdef UNC
f->dx = (f->x)*(m->dx/m->x + a->dx/a->x);
#endif
return 0;
}
int main(){
Foo m; m.x = 3.0;
Foo a; a.x = 2.0;
#ifdef UNC
m.dx = 0.3;
a.dx = 0.2;
#endif
Foo f;
force(&m,&a,&f);
printf(" f is %f \n", f.x);
#ifdef UNC
printf("df is %f \n", f.dx);
#endif
return 0;
}
You could define some macros as follows, which would neaten things up....
#ifdef UNC
#define SetDx(f, v) (f)->dx = (v)
#define PRINT_UNC(x) printf x
#else
#define SetDx(f, v)
#define PRINT_UNC(x)
#endif
Then write your code as
int force(Foo* m, Foo* a, Foo* f){
f->x = m->x * a->x;
SetDx(f, (f->x)*(m->dx/m->x + a->dx/a->x));
return 0;
}
int main(){
Foo m; m.x = 3.0;
Foo a; a.x = 2.0;
SetDx(&m, 0.3);
SetDx(&a, 0.2);
Foo f;
force(&m,&a,&f);
printf(" f is %f \n", f.x);
PRINT_UNC(("df is %f \n", f.dx));
return 0;
}
This way you can minimise the number of #ifdef block in your code, which make things difficult to read. When you turn of the main define, the SetDx
and PRINT_UNC
macros will do nothing. (Note the need to double brackets in the PRINT_UNC
macro).
Just a quick question about the part of your question that says:
...slowing down the compiler by processing all these unnecessary items once UNC is turned off...
Are you worried about the pre-processing speed? I though this sounded like you might be worrying that the compiler was taking time compiling the ifdef as a kind of switch... if that's the case, don't worry, the pre-processor kills the undefined blocks so the compiler never sees them. If you're worried about pre-processing speed, there's not a lot you can do I don't think, but I wouldn't have thought the pre-processing overhead would be significant?