[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-gnulib] addition: minmax.h

From: Bruno Haible
Subject: Re: [Bug-gnulib] addition: minmax.h
Date: Thu, 23 Jan 2003 14:01:40 +0100 (CET)

Paul Eggert writes:
> > /* Before we define the following symbols we get the <limits.h> file
> >    since otherwise we get redefinitions on some systems.  */
> > #include <limits.h>
> I'd rather omit this #include.  On some systems, <limits.h> imports a
> boatload of undesirable symbols.

Such symbols may be undesirable in autoconf snippets, but they are
harmless in application code. I use <limits.h> in dozens of gettext
source files, on all platforms including HP-UX and Solaris, and I
haven't seen negative effects of it.

The same way as "gettext.h" includes <locale.h>, although this is only
needed because of Solaris and doesn't hurt otherwise, the same way
"minmax.h" can include <limits.h> and it doesn't hurt.

> <minmax.h> should #define only MIN and MAX.  It should be the caller's
> responsibility to include <minmax.h> after any system file that could
> define MIN or MAX.

I don't want to go back to the times (around 1990) where users had to
remember ordering restrictions like "you have to #include
<sys/select.h> before <sys/types.h> not afterwards because of such and
such OS". gnulib shall be easy to use. Currently gnulib has no
#include ordering restrictions - minmax.h would be the first one.

> Also, this is more of a documentation issue, but it would be helpful
> to add a comment like this:
> /* Caveat: MIN and MAX might not return the minimum and maximum of
>    their two arguments, if the arguments have different types or have
>    unusual floating-point values.  For example, on a typical
>    two's-complement host with 32-bit int, 64-bit long long, and 64-bit
>    double:
>      MAX (-1, 2147483648) returns 4294967295.
>      MAX (9007199254740992.0, 9007199254740993) returns 9007199254740992.0.
>      MAX (NaN, 0.0) returns 0.0.
>      MAX (+0.0, -0.0) returns -0.0.
>    and in each case the answer is in some sense bogus.  */

Interesting! I didn't know this. Added.

> > #ifndef MAX
> > # if __STDC__ && defined __GNUC__ && __GNUC__ >= 2
> > #  define MAX(a,b) (__extension__                                       \
> >                  ({__typeof__ (a) _a = (a);                             \
> >                    __typeof__ (b) _b = (b);                             \
> >                    _a > _b ? _a : _b;                                   \
> >                   }))
> > # else
> > #  define MAX(a,b) ((a) > (b) ? (a) : (b))
> > # endif
> > #endif
> A minor nit: the recommended GNU coding style is to put a
> space after the commas.

I avoid to do this because then it is very tempting to use the GNU
coding style for the entire

          #  define MAX (a, b) ...

and then the flow of gcc error messages doesn't really help me
isolating the problem.

> More important, the semantics of this __extension__-based definition
> differ between GCC and compilers, which can lead to nonportable code
> if people develop using GCC and then deploy with other compilers.

You have such unportabilities anyway, regarding e.g. a[i++] = b[i++],
or side effects depending on argument order etc.

The point of the __extension__ is to let gcc make optimal code. I
don't care a lot about other compilers.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]