Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Jul 2010 23:32:40 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Jung-uk Kim <jkim@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r209842 - head/lib/libstand
Message-ID:  <20100710230758.S60090@delplex.bde.org>
In-Reply-To: <201007090525.o695PEmj038278@svn.freebsd.org>
References:  <201007090525.o695PEmj038278@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 9 Jul 2010, Jung-uk Kim wrote:

> Log:
>  Fix build by defining MAX() macro here.
>
> Modified:
>  head/lib/libstand/printf.c

Arrgh.  The unsafe macros MAX() and MIN() were deprecated in the kernel,
but this has been broken (in 2001 for NetBSD and 2003 for FreeBSD).
Use of MAX() in kern/subr_prf.c was a style bug.  Older code in
subr_prf.c still uses the min()/max() family of inline functions (just
1 instance).

> Modified: head/lib/libstand/printf.c
> ==============================================================================
> --- head/lib/libstand/printf.c	Fri Jul  9 00:38:00 2010	(r209841)
> +++ head/lib/libstand/printf.c	Fri Jul  9 05:25:14 2010	(r209842)

Use of MAX() here was more than a style bug, since MAX() didn't exist.
libstand seems to have a full min()/max() family, modulo the usual bugs
and some bitrot (libkern never had uqmax()/min(), ...; libstand is missing
the addition of omax()/min(), which is unimportant since it doesn't use them,
but OTOH it doesn't use most of the ones that it has).

> @@ -151,6 +151,7 @@ ksprintn(char *nbuf, uintmax_t num, int
> static int
> kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
> {
> +#define	MAX(a, b) (((a) > (b)) ? (a) : (b))

One reason FreeBSD brought back the MAX() and MIN() mistakes was that
definitions like the above were duplicated in many places in code not
following normal kernel APIs.

> #define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
> 	char nbuf[MAXNBUF];
> 	char *d;
>

The max() and min() families are hard to use because using them requires
knowing the types of the arg.

It is possible to write safe type-generic macros for max() and min() using
gcc features (mainly __typeof()).  gcc info gives examples of these.  I
didn't want to unportabilize the kernel by committing my versions of these,
but once used them to find some type mismatches in the misuse of the
max()/min() family.

The type-generic versions should be safe macros named max() and min(), but
unfortunately these good names are taken for the old API.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100710230758.S60090>