[tz] source code question regarding localtime.c PS

Paul Eggert eggert at cs.ucla.edu
Wed Aug 7 23:12:00 UTC 2013


On 08/07/2013 09:51 AM, Clive D.W. Feather wrote:
> In principle UINTMAX_MAX could be larger than the largest value
> representable in time_t if it is (say) float. If so, the implicit
> conversion to float is undefined and you haven't solved the problem.

True, that's an extra assumption that should be documented.
And come to think of it there's no point using UINTMAX_MAX.
Here's a further patch that implements this, which I've pushed
to the experimental repository.

>From 3638e641e8d05f8e8dd86a7c6f216e3527e2dccd Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert at cs.ucla.edu>
Date: Wed, 7 Aug 2013 16:08:39 -0700
Subject: [PATCH] Don't bother with uintmax_t in previous change.

See the thread starting with Clive D.W. Feather's comments in
<http://mm.icann.org/pipermail/tz/2013-August/019496.html>.
* localtime.c (truncate_time): Don't bother with uintmax_t,
as using it doesn't help on any known platform.
* private.h (UINTMAX_MAX): Remove.
---
 localtime.c | 21 +++++++++------------
 private.h   |  6 ------
 2 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/localtime.c b/localtime.c
index 353c73b..3814a6a 100644
--- a/localtime.c
+++ b/localtime.c
@@ -1267,20 +1267,17 @@ truncate_time(time_t t)
 	** INTMAX_MAX is converted to a larger time_t value before it
 	** is compared.
 	**
-	** On all platforms that we know of, if a time value is
-	** outside intmax_t/uintmax_t range, then it is an integer so we can
-	** simply return it.  There's no simple, portable way to check this.
+	** On all platforms that we know of (1) it is safe to compare
+	** INTMAX_MIN and INTMAX_MAX to floating-point values without
+	** worrying about undefined behavior due to floating-point
+	** overflow on conversion, and (2) any time_t value outside
+	** intmax_t range is an integer so we can simply return it.
+	** We know of no simple, portable way to check these assumptions.
 	** If you know of a counterexample platform, please report a bug.
 	*/
-	if (!TYPE_INTEGRAL(time_t)) {
-		if (INTMAX_MIN < t && t < INTMAX_MAX) {
-			intmax_t i = t;
-			return i;
-		}
-		if (0 <= t && t < UINTMAX_MAX) {
-			uintmax_t i = t;
-			return i;
-		}
+	if (!TYPE_INTEGRAL(time_t) && INTMAX_MIN < t && t < INTMAX_MAX) {
+		intmax_t i = t;
+		return i;
 	}
 
 	return t;
diff --git a/private.h b/private.h
index f00a926..bf6bad2 100644
--- a/private.h
+++ b/private.h
@@ -186,15 +186,9 @@ typedef long intmax_t;
 # if defined ULLONG_MAX || defined __LONG_LONG_MAX__
 typedef unsigned long long uintmax_t;
 #  define PRIuMAX "llu"
-#  ifdef ULLONG_MAX
-#   define UINTMAX_MAX ULLONG_MAX
-#  else
-#   define UINTMAX_MAX (__LONG_LONG_MAX__ * 2ULL + 1)
-#  endif
 # else
 typedef unsigned long uintmax_t;
 #  define PRIuMAX "lu"
-#  define UINTMAX_MAX ULONG_MAX
 # endif
 #endif
 
-- 
1.8.1.2




More information about the tz mailing list