D_Liver
D_Liver

Reputation: 55

Order matters in C arithmetic?

I'm tutoring some students in basic C, but really confused about something in a crazy basic C program that I'm writing up.

I have the following

...
#define RATEM1 0.015
#define RATEM2 0.025
...
#define THRESHM 100000.00
...
#define BASE0 0.00
....
#define BASEM (BASE0 + RATEM1*THRESHM);

void ex3_8() {
    double gross, medicare, net;
    ... /* Reading in gross, performing other calculations, etc. */
    if (gross <= THRESHM) {
        medicare = RATEM1 * gross;
    } else {
        medicare = (gross - THRESHM) * RATEM2 + BASEM;
    }
    printf("Medicare: %9.2f\n", medicare);
    net = gross - tax - medicare;
    printf("net income         $%9.2f\n", net);
}
int main(int argc, char *argv[]) {
    ex3_8();
    return 0;
}

This works. But if I change the second medicare line to medicare = BASEM + (gross - THRESHM) * RATEM2; then I get an unused variable warning: warning: expression result unused [-Wunused-value].

Can anyone tell what's going on?

Upvotes: 2

Views: 104

Answers (1)

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140168

Look what happens when you use -E switch to show preprocessor output in gcc:

void ex3_8() {
    double gross, medicare, net;
    ...
    if (gross <= 100000.00) {
        medicare = 0.015 * gross;
    } else {
        medicare = (0.00 + 0.015*100000.00); + (gross - 100000.00) * 0.025;
    }

}

Since your macro ends with ; (which is a big no-no), the expression ends with the macro, and the rest is just a computation that is not used, hence the (very useful) warning.

In that case, the + operator is a unary + which is accepted by the compiler. If it was * you'd have gotten an error (cryptic as well, with only the non-preprocessed output).

Solution (as mentionned in comments): remove the ; in the end.

To be really safe about your macro, parenthesise every member as each member is a macro (same with macro parameters) which could have computations in it which would make computations wrong because of operator precedence:

#define BASEM ((BASE0) + (RATEM1)*(THRESHM))

Note: If you have several statements, always enclose them in do {} while(0) so you don't have to put a ; in the end as well.

Upvotes: 4

Related Questions