MAX.3, MIN.3: New page (and link page) to document MAX() and MIN()

Message ID 20210512204311.19399-1-alx.manpages@gmail.com
State Superseded
Headers show
Series
  • MAX.3, MIN.3: New page (and link page) to document MAX() and MIN()
Related show

Commit Message

Adhemerval Zanella via Libc-alpha May 12, 2021, 8:43 p.m.
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>

---

Example tested:

$ man max \
  | sed -n /^EXAMPLES/,/^[[:alpha:]]/p \
  | grep -v '^[[:alpha:]]' \
  | cc -Wall -Wextra -Werror -x c -;
$ ./a.out 65 38
MAX(65, 38) is 65


 man3/MAX.3 | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 man3/MIN.3 |  1 +
 2 files changed, 86 insertions(+)
 create mode 100644 man3/MAX.3
 create mode 100644 man3/MIN.3

-- 
2.31.1

Comments

Paul Eggert May 12, 2021, 9:17 p.m. | #1
On 5/12/21 1:43 PM, Alejandro Colomar via Libc-alpha wrote:

> +If any of the arguments is of a floating-point type,


"any" -> "either"

> +these macros shouldn't be used


That's too strong. It's often OK to use MAX and MIN on floating point 
arguments.

> +The arguments may be evaluated more than once,

> +and their types might be promoted to a common type

> +if both arguments aren't of the same type.


This is muddy. It should state clearly that even if A and B are both 
integers, MAX (a, b) might not return their maximum. For example, on a 
typical C platform today, MAX (-1, 2147483648) returns 4294967295 and 
MIN (-1, 2147483648) returns 2147483648.

Also, the man page shouldn't require the arguments to be evaluated at 
least once. It's possible to implement MAX so that it sometimes doesn't 
evaluate one argument, and the documentation shouldn't preclude such an 
implementation.

The man page should more specifically mention that although MIN and MAX 
are defined <sys/param.h> on GNU platforms, other platforms define them 
elsewhere or not at all.

> +These macros return the value of one of their arguments,


Unfortunately they don't necessarily do that, as shown in the MAX 
example above.

I suggest looking at the remarks about MAX and MIN that are made here, 
and incorporating the useful parts of these remarks into the man page:

https://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/minmax.h
Adhemerval Zanella via Libc-alpha May 12, 2021, 10:32 p.m. | #2
Hello Paul,

On 5/12/21 11:17 PM, Paul Eggert wrote:
> On 5/12/21 1:43 PM, Alejandro Colomar via Libc-alpha wrote:

> 

>> +If any of the arguments is of a floating-point type,

> 

> "any" -> "either"


Okay.  I thought that either meant XOR, but now I learnt it may also be OR.

> 

>> +these macros shouldn't be used

> 

> That's too strong. It's often OK to use MAX and MIN on floating point

> arguments.


Yup, I changed it a few minutes later.

> 

>> +The arguments may be evaluated more than once,

>> +and their types might be promoted to a common type

>> +if both arguments aren't of the same type.

> 

> This is muddy. It should state clearly that even if A and B are both

> integers, MAX (a, b) might not return their maximum. For example, on a

> typical C platform today, MAX (-1, 2147483648) returns 4294967295 and

> MIN (-1, 2147483648) returns 2147483648.


Hmm, yes, I'll add a BUGS section for this.  Usual arithmetic
conversions and why you should avoid them :)

> 

> Also, the man page shouldn't require the arguments to be evaluated at

> least once. It's possible to implement MAX so that it sometimes doesn't

> evaluate one argument, and the documentation shouldn't preclude such an

> implementation.


In which case they might not be evaluated at all?  I'm curious.
Maybe if one of the arguments is literal NAN and the implementation
raises an exception for it?

> 

> The man page should more specifically mention that although MIN and MAX

> are defined <sys/param.h> on GNU platforms, other platforms define them

> elsewhere or not at all.


Okay.

> 

>> +These macros return the value of one of their arguments,

> 

> Unfortunately they don't necessarily do that, as shown in the MAX

> example above.


Fixed.

> 

> I suggest looking at the remarks about MAX and MIN that are made here,

> and incorporating the useful parts of these remarks into the man page:

> 

> https://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/minmax.h

> 


Okay.

Thank you very much!

Cheers,

Alex

-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/
Paul Eggert May 12, 2021, 10:39 p.m. | #3
On 5/12/21 3:32 PM, Alejandro Colomar (man-pages) wrote:
> In which case they might not be evaluated at all?  I'm curious.

> Maybe if one of the arguments is literal NAN and the implementation

> raises an exception for it?


Or, one argument of MIN might be negative and the other might be 
unsigned short. In that case, the unsigned short argument need not be 
evaluated at all. Admittedly not something we'd be likely to optimize 
for, but the documentation shouldn't preclude such optimization.

Patch

diff --git a/man3/MAX.3 b/man3/MAX.3
new file mode 100644
index 000000000..e203b5ca4
--- /dev/null
+++ b/man3/MAX.3
@@ -0,0 +1,85 @@ 
+.\" Copyright (C) 2021 Alejandro Colomar <alx.manpages@gmail.com>
+.\"
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
+.\"
+.TH MAX 3 2020-11-01 "Linux" "Linux Programmer's Manual"
+.SH NAME
+MAX, MIN \- maximum or minimum of two values
+.SH SYNOPSIS
+.nf
+.B #include <sys/param.h>
+.PP
+.BI MAX( a ", " b );
+.BI MIN( a ", " b );
+.fi
+.SH DESCRIPTION
+These macros return the maximum or minimum of
+.I a
+and
+.IR b .
+.PP
+If any of the arguments is of a floating-point type,
+these macros shouldn't be used; see
+.BR fmax (3)
+or
+.BR fmin (3)
+instead.
+.PP
+The arguments may be evaluated more than once,
+and their types might be promoted to a common type
+if both arguments aren't of the same type.
+.SH RETURN VALUE
+These macros return the value of one of their arguments,
+according to their relationship.
+.SH ERRORS
+These macros may raise the "invalid" floating-point exception
+when any of the arguments is NaN.
+.SH CONFORMING TO
+These macros are present in glibc and the BSDs.
+.SH EXAMPLES
+.EX
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/param.h>
+
+int
+main(int argc, char *argv[])
+{
+    int a, b, x;
+
+    if (argc != 3) {
+        fprintf(stderr, "Usage: %s <num> <num>\en", argv[0]);
+        exit(EXIT_FAILURE);
+    }
+
+    a = atoi(argv[1]);
+    b = atoi(argv[2]);
+    x = MAX(a, b);
+    printf("MAX(%d, %d) is %d\en", a, b, x);
+
+    exit(EXIT_SUCCESS);
+}
+.EE
+.SH SEE ALSO
+.BR fmax (3),
+.BR fmin (3)
diff --git a/man3/MIN.3 b/man3/MIN.3
new file mode 100644
index 000000000..9938abda2
--- /dev/null
+++ b/man3/MIN.3
@@ -0,0 +1 @@ 
+.so man3/MAX.3