Question

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;
}
Was it helpful?

Solution

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?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top