* Re: min/max macros
1997-12-11 9:17 min/max macros Bill Ahlbrandt
@ 1997-12-11 13:03 ` dave madden
1997-12-11 13:03 ` Michael A. Benzinger
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: dave madden @ 1997-12-11 13:03 UTC (permalink / raw)
To: bahlbr; +Cc: egcs
At last, an egcs question that *I* can answer! :-) (Unfortunately,
it's not really an egcs question, but a C/C++ question. Anyway...)
=>From: Bill Ahlbrandt <bahlbr@icdata.com>
=>...
=>I "coded" my own and used them as follows:
=>
=>#define max(a,b) (((a) > (b)) ? (a) : (b))
=>#define min(a,b) (((a) < (b)) ? (a) : (b))
=>
=>Is it generally a bad plan to use macros like this? Are there any
=>known problems with egcs involving macros such as these?
min/max macros are not inherently bad, as long as you understand that
they evaluate their arguments more than once. For the simple case,
they work as you'd expect, but if you do something like:
double x = min( sqrt(x), sqrt(y) );
int a = 1;
int b = 2;
int c = max( a++, b++ );
you'll be inefficient (first example) or undefined (second example).
Min/max are better handled by inline functions; in c++ you can even
create a function template so that you can have min/max defined for
any type:
template <class T> const T &
min( const T &a, const T &b )
{
return (a < b) ? a : b;
}
d.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: min/max macros
1997-12-11 9:17 min/max macros Bill Ahlbrandt
1997-12-11 13:03 ` dave madden
@ 1997-12-11 13:03 ` Michael A. Benzinger
1997-12-11 13:43 ` [EGCS] " Marc Lehmann
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Michael A. Benzinger @ 1997-12-11 13:03 UTC (permalink / raw)
To: Bill Ahlbrandt, egcs
At 11:14 AM 12/11/97 -0600, you wrote:
>#define max(a,b) (((a) > (b)) ? (a) : (b))
>#define min(a,b) (((a) < (b)) ? (a) : (b))
>
>After discovering that max in particular was not yielding the desired
results, I coded these macros as functions. All of my problems went away.
>
>Is it generally a bad plan to use macros like this? Are there any known
problems with egcs involving macros such as these?
Bill,
The functions are better than the macros for this very reason:
int x=2;
int y=1;
int z = max(x++,y);
Your intentions are to have 'z' equal to '2' and 'x' equal to '3'. However,
'x' is actually equal to '4'. Why? Because the macro code hides a nasty
gotcha. The code when expanded looks like this:
int z = (((x++) > (y)) ? (x++) : (y));
You will note that 'x++' is actuall evaluated twice. With a function of
the Standard Library function 'max', this will not happen. The argument
is only evaluated and incremented once, as you would expect.
Mike Benzinger
-------------------------------------------------------------
Michael A. Benzinger
Principal
SABRE Technology Solutions Phone: +1 817-264-6820
1 E. Kirkwood Blvd. Fax: +1 817-264-3504
Southlake, TX 76092 e-mail: mbenz@sabre.com
U.S.A. bzinger@iName.com
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [EGCS] min/max macros
1997-12-11 9:17 min/max macros Bill Ahlbrandt
1997-12-11 13:03 ` dave madden
1997-12-11 13:03 ` Michael A. Benzinger
@ 1997-12-11 13:43 ` Marc Lehmann
1997-12-11 13:43 ` Gerald Pfeifer
1997-12-12 7:51 ` Paul Koning
4 siblings, 0 replies; 10+ messages in thread
From: Marc Lehmann @ 1997-12-11 13:43 UTC (permalink / raw)
To: egcs
On Thu, Dec 11, 1997 at 11:14:41AM -0600, Bill Ahlbrandt wrote:
> I have noticed that these macros are not always available and not always in the same place.
there is no standard for them, and they are not part of egcs.
> Specifically, with egcs, they seem to be in curses.h
curses.h has nothing to do with egcs.
> I "coded" my own and used them as follows:
>
> #define max(a,b) (((a) > (b)) ? (a) : (b))
> #define min(a,b) (((a) < (b)) ? (a) : (b))
these are fine, as long as you are aware of them being macros...
there's probably no better way to do this in plain C, using
gcc extensions, you can code macros without side effects.
> Is it generally a bad plan to use macros like this? Are there any known
No..
> problems with egcs involving macros such as these?
No.. It would be much better if you could provide us with more information
regarding the problems you have.
-----==- |
----==-- _ |
---==---(_)__ __ ____ __ Marc Lehmann +--
--==---/ / _ \/ // /\ \/ / pcg@goof.com |e|
-=====/_/_//_/\_,_/ /_/\_\ --+
The choice of a GNU generation |
|
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: min/max macros
1997-12-11 9:17 min/max macros Bill Ahlbrandt
` (2 preceding siblings ...)
1997-12-11 13:43 ` [EGCS] " Marc Lehmann
@ 1997-12-11 13:43 ` Gerald Pfeifer
1997-12-11 17:57 ` [EGCS] " Marc Lehmann
1997-12-12 7:51 ` Paul Koning
4 siblings, 1 reply; 10+ messages in thread
From: Gerald Pfeifer @ 1997-12-11 13:43 UTC (permalink / raw)
To: egcs; +Cc: Bill Ahlbrandt
On Thu, 11 Dec 1997, Bill Ahlbrandt wrote:
> I "coded" my own and used them as follows:
>
> #define max(a,b) (((a) > (b)) ? (a) : (b))
> #define min(a,b) (((a) < (b)) ? (a) : (b))
That is a big no-no: Absolutely no performance benefits with any decent
compiler but nasty side effects.
> After discovering that max in particular was not yielding the desired
> results [...]
You didn't happen to use "max(i++,prev_max)" or similar, did you?
For that expands to
(((i++) > (prev_max)) ? (i++) : (prev_max))
which may increment i twice as an -- usually unintended -- side-effect.
Hope this helps,
Gerald
--
Gerald Pfeifer (Jerry) Vienna University of Technology
pfeifer@dbai.tuwien.ac.at http://www.dbai.tuwien.ac.at/~pfeifer/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [EGCS] Re: min/max macros
1997-12-11 13:43 ` Gerald Pfeifer
@ 1997-12-11 17:57 ` Marc Lehmann
1997-12-11 19:51 ` Joe Buck
0 siblings, 1 reply; 10+ messages in thread
From: Marc Lehmann @ 1997-12-11 17:57 UTC (permalink / raw)
To: egcs
> > #define max(a,b) (((a) > (b)) ? (a) : (b))
> > #define min(a,b) (((a) < (b)) ? (a) : (b))
>
> That is a big no-no: Absolutely no performance benefits with any decent
> compiler but nasty side effects.
so egcs isn't a decent compiler?
for example, the macro-max(2,3) will be evaluated at compile time,
while the function-max(2,3) won't...
this get's even worse on things like:
int mult(int a, int b) { return a*b; };
mult(a,3) will result in an "imul 3" on x86... definitely
slower than a lea, for example.
-----==- |
----==-- _ |
---==---(_)__ __ ____ __ Marc Lehmann +--
--==---/ / _ \/ // /\ \/ / pcg@goof.com |e|
-=====/_/_//_/\_,_/ /_/\_\ --+
The choice of a GNU generation |
|
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [EGCS] Re: min/max macros
1997-12-11 17:57 ` [EGCS] " Marc Lehmann
@ 1997-12-11 19:51 ` Joe Buck
1997-12-12 10:18 ` Marc Lehmann
0 siblings, 1 reply; 10+ messages in thread
From: Joe Buck @ 1997-12-11 19:51 UTC (permalink / raw)
To: egcs
> > > #define max(a,b) (((a) > (b)) ? (a) : (b))
> > > #define min(a,b) (((a) < (b)) ? (a) : (b))
> >
> > That is a big no-no: Absolutely no performance benefits with any decent
> > compiler but nasty side effects.
>
> so egcs isn't a decent compiler?
>
> for example, the macro-max(2,3) will be evaluated at compile time,
> while the function-max(2,3) won't...
The function max(2,3) will indeed be evaluated at compile time, if it is
inlined.
> this get's even worse on things like:
>
> int mult(int a, int b) { return a*b; };
>
> mult(a,3) will result in an "imul 3" on x86... definitely
> slower than a lea, for example.
Same for mult: if it is inlined, it will be evaluated at compile time if
given constant arguments.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: min/max macros
1997-12-11 19:51 ` Joe Buck
@ 1997-12-12 10:18 ` Marc Lehmann
0 siblings, 0 replies; 10+ messages in thread
From: Marc Lehmann @ 1997-12-12 10:18 UTC (permalink / raw)
To: egcs
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1475 bytes --]
> > so egcs isn't a decent compiler?
> >
> > for example, the macro-max(2,3) will be evaluated at compile time,
> > while the function-max(2,3) won't...
>
> The function max(2,3) will indeed be evaluated at compile time, if it is
> inlined.
sorry, I was just too fast here in replyÃing (and I left the [EGCS] in, soory again ;)
> > this get's even worse on things like:
> >
> > int mult(int a, int b) { return a*b; };
> >
> > mult(a,3) will result in an "imul 3" on x86... definitely
> > slower than a lea, for example.
>
> Same for mult: if it is inlined, it will be evaluated at compile time if
> given constant arguments.
no, mult(a,3) results in:
movl 4(%esp),%eax
imull $3,%eax,%eax
ret
which is highly suboptimal.. a mult(4,5), though, will be evaluated at compile
time. But macros *are* faster than inline functions, despite what the
documentation tells us.
---------------------------------------------------------------------
for a pentium-optimizing gcc, look at http://www.gcc.ml.org/
-----==- |
----==-- _ |
---==---(_)__ __ ____ __ Marc Lehmann +--
--==---/ / _ \/ // /\ \/ / pcg@goof.com |e|
-=====/_/_//_/\_,_/ /_/\_\ --+
The choice of a GNU generation |
|
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: min/max macros
1997-12-11 9:17 min/max macros Bill Ahlbrandt
` (3 preceding siblings ...)
1997-12-11 13:43 ` Gerald Pfeifer
@ 1997-12-12 7:51 ` Paul Koning
4 siblings, 0 replies; 10+ messages in thread
From: Paul Koning @ 1997-12-12 7:51 UTC (permalink / raw)
To: egcs
>>>>> "Bill" == Bill Ahlbrandt <bahlbr@icdata.com> writes:
Bill> I have noticed that these macros are not always available and
Bill> not always in the same place. Specifically, with egcs, they
Bill> seem to be in curses.h
Bill> I "coded" my own and used them as follows:
Bill> #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b)
Bill> (((a) < (b)) ? (a) : (b))
Bill> After discovering that max in particular was not yielding the
Bill> desired results, I coded these macros as functions. All of my
Bill> problems went away.
It's always dangerous to create macros that use a macro argument more
than once. You will get the wrong results if the macro is called with
an actual argument that has side effects (e.g., max (i++, j++) ).
Apart from that, functions have the benefit of type checking.
For these reasons, I tend to use functions when I can. You can
declare them "static inline" to get the benefits without any
performance penalties.
paul
^ permalink raw reply [flat|nested] 10+ messages in thread