Subject: Documentation of abs(3), div(3) etc.
To: None <tech-userlevel@NetBSD.org>
From: Christian Biere <christianbiere@gmx.de>
List: tech-userlevel
Date: 02/07/2007 01:37:16
--+pHx0qQiF2pBVqBT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

(moved to tech-userlevel on request)

the manpages for abs(3) and its variants define behavior for the "most negative
integer" whereas the standard explicity states that the behavior is undefined
if the result cannot be represented.

This is a lie anyway because the code looks like

	return a < 0 ? -a : a;

whereas it obviously means

	return a < 0 ? -(unsigned)a : a;

This would yield the documented behavior but of course it doesn't change the
standard.

For div(3) et al. a similar issue is not documented at all.

	div(x, 0) -> undefined behavior
	div(INT_MIN, -1) -> undefined behavior

The latter is only true if the implementation uses two's complement i.e.
-INT_MAX > INT_MIN. The standard isn't as explicit about this case but just
states that unrepresentable results cause undefined behavior. Maybe I've
overseen some case, otherwise I'd prefer being explicit about this because the
reader might easily assume it's an esoteric and irrelevant caveat.

I have attached a patch for the manpages. I've also changed "BUGS" to "CAVEAT"
because these aren't bugs, it's broken by design.

-- 
Christian

--+pHx0qQiF2pBVqBT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="current.udif"

Index: stdlib/abs.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/abs.3,v
retrieving revision 1.12
diff -u -p -r1.12 abs.3
--- stdlib/abs.3	7 Aug 2003 16:43:37 -0000	1.12
+++ stdlib/abs.3	7 Feb 2007 00:01:26 -0000
@@ -71,5 +71,5 @@ The
 .Fn abs
 function conforms to
 .St -ansiC .
-.Sh BUGS
-The absolute value of the most negative integer remains negative.
+.Sh CAVEAT
+Passing the most negative integer has undefined behavior.
Index: stdlib/labs.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/labs.3,v
retrieving revision 1.10
diff -u -p -r1.10 labs.3
--- stdlib/labs.3	7 Aug 2003 16:43:41 -0000	1.10
+++ stdlib/labs.3	7 Feb 2007 00:01:26 -0000
@@ -63,5 +63,5 @@ The
 function
 conforms to
 .St -ansiC .
-.Sh BUGS
-The absolute value of the most negative integer remains negative.
+.Sh CAVEAT
+Passing the most negative integer has undefined behavior.
Index: stdlib/llabs.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/llabs.3,v
retrieving revision 1.6
diff -u -p -r1.6 llabs.3
--- stdlib/llabs.3	8 Sep 2003 17:54:33 -0000	1.6
+++ stdlib/llabs.3	7 Feb 2007 00:01:26 -0000
@@ -63,5 +63,5 @@ The
 function
 conforms to
 .St -isoC-99 .
-.Sh BUGS
-The absolute value of the most negative integer remains negative.
+.Sh CAVEAT
+Passing the most negative integer has undefined behavior.
Index: stdlib/qabs.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/qabs.3,v
retrieving revision 1.8
diff -u -p -r1.8 qabs.3
--- stdlib/qabs.3	7 Aug 2003 16:43:42 -0000	1.8
+++ stdlib/qabs.3	7 Feb 2007 00:01:26 -0000
@@ -58,5 +58,5 @@ returns the absolute value of the quad i
 .Xr labs 3 ,
 .Xr llabs 3 ,
 .Xr math 3
-.Sh BUGS
-The absolute value of the most negative integer remains negative.
+.Sh CAVEAT
+Passing the most negative integer has undefined behavior.
Index: stdlib/div.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/div.3,v
retrieving revision 1.11
diff -u -p -r1.11 div.3
--- stdlib/div.3	7 Aug 2003 16:43:39 -0000	1.11
+++ stdlib/div.3	7 Feb 2007 00:01:26 -0000
@@ -68,3 +68,6 @@ The
 function
 conforms to
 .St -ansiC .
+.Sh CAVEAT
+If the denominator is zero or the numerator is the most negative integer and
+the denominator is -1, the behavior is undefined.
Index: stdlib/ldiv.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/ldiv.3,v
retrieving revision 1.12
diff -u -p -r1.12 ldiv.3
--- stdlib/ldiv.3	7 Aug 2003 16:43:41 -0000	1.12
+++ stdlib/ldiv.3	7 Feb 2007 00:01:26 -0000
@@ -70,3 +70,6 @@ The
 function
 conforms to
 .St -ansiC .
+.Sh CAVEAT
+If the denominator is zero or the numerator is the most negative integer and
+the denominator is -1, the behavior is undefined.
Index: stdlib/lldiv.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/lldiv.3,v
retrieving revision 1.6
diff -u -p -r1.6 lldiv.3
--- stdlib/lldiv.3	8 Sep 2003 17:54:33 -0000	1.6
+++ stdlib/lldiv.3	7 Feb 2007 00:01:26 -0000
@@ -70,3 +70,6 @@ The
 function
 conforms to
 .St -isoC-99 .
+.Sh CAVEAT
+If the denominator is zero or the numerator is the most negative integer and
+the denominator is -1, the behavior is undefined.
Index: stdlib/qdiv.3
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/qdiv.3,v
retrieving revision 1.8
diff -u -p -r1.8 qdiv.3
--- stdlib/qdiv.3	7 Aug 2003 16:43:42 -0000	1.8
+++ stdlib/qdiv.3	7 Feb 2007 00:01:26 -0000
@@ -64,3 +64,6 @@ and
 .Xr ldiv 3 ,
 .Xr lldiv 3 ,
 .Xr math 3
+.Sh CAVEAT
+If the denominator is zero or the numerator is the most negative integer and
+the denominator is -1, the behavior is undefined.

--+pHx0qQiF2pBVqBT--