-3

So i'm using a preprocessing macro for this basic square function :

#define SQUARE(a) a*a

it is then passed to these functions, to perform these tasks respectively:

double f(double x) {
    return SQUARE(x);
}
double g(double x) {
    return SQUARE(1-x);
}
double h(double x) {
    return 1/SQUARE(x);
}

with such functions, for g(x) and h(x) i'm getting results such as:

 g(2) = -3, h(2) = 1
 g(3) = -5, h(3) = 1
 g(4) = -7, h(4) = 1
 etc...

I have changed the functions to get their expected results, but I'm curious as to what is happening in the above functions to give me such strange results?

Community
  • 1
  • 1
NoName
  • 49
  • 4

1 Answers1

1

SQUARE(1-x) will be expanded to 1-x*1-x which is not correct at all.

It would be much better to use a function instead of a macro. A function only evaluates the parameter once.

double square(double a)
{ return a * a; }
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • The point of my question was not a code evaluation, it was asking what is happening behind the scenes which gives me results. This code, which I know full well is incorrect, is not in use in my final program, I just want to know why its wrong – NoName Nov 16 '16 at 13:57
  • 3
    @NoName Literally the first sentence of this answer explains what’s happening behind the scenes. – Konrad Rudolph Nov 16 '16 at 13:58
  • Thanks for the link about the parenthesis , but I don't see why this post deserved to get voted down, I was simply given this formula and asked to give a fix, but i solved it by changing the macros to this `#define f(x) x*x #define g(x) f((1-x)) #define h(x) 1/(f(x))` , the original was given without parenthesis, and I was unaware, that that was the cause of the issue – NoName Nov 16 '16 at 14:03
  • @NoName The parentheses are *one of the problems*, but there are more (and your “fixed” code doesn’t even fix the parenthesis problem). The real solution here is not to use macros. Out of interest, why are you using a macro instead of a function at all? What do you think this accomplishes? In fact, a macro serves *no* purpose here and is simply wrong. Use a function. – Konrad Rudolph Nov 16 '16 at 14:06
  • I just explained that above, I was given a macro, and tasked to fix it (it was a question for Uni assignment) in context of these functions, which I did, but wasn't sure why it wasn't working in the first place, but like Bo said, it was due to parenthesis and false expansion, don't worry, I don't want to be using macros and more than you want me to – NoName Nov 16 '16 at 14:09
  • @Bo - you mention that you solved this by fixing g and h. The correct place would be to fix f itself, rather than everyone that calls it. A first pass would be `#define f(x) (x)*(x)`. But - that still suffers other problems, such as double evaluation. For example `f(getNextNum())` would expand to `(getNextNum())*(getNextNum())` which would not do the expected thing (get the next number and square it), but would actually get the next two nums and multiply them... – Allison Lock Nov 16 '16 at 15:00
  • ... To solve that you now need do something like `#define sq(x) [](double y){return y*y;}(x)`, but now all you have is a function wrapped up inside a macro. Final answer: This type of macro _just can't_ be "fixed" – Allison Lock Nov 16 '16 at 15:31