0

UBSAN complains about undefined behavior for when I run the antiword utility:

runtime error: left shift of 1 by 63 places cannot be represented in type 'time_t' (aka 'long')

The error is triggered by the macros for TIME_T_MIN and TIME_T_MAX below.

#if !defined(TIME_T_MIN)
#define TIME_T_MIN      ((time_t)0 < (time_t)-1 ?\
                (time_t)0 :\
                (time_t)1 << (sizeof(time_t) * CHAR_BIT - 1))
#endif /* TIMER_T_MIN */

#if !defined(TIME_T_MAX)
#if defined(__TURBOC__) /* Turbo C chokes on the subtraction below */
#define TIME_T_MAX      (LONG_MAX)
#else   /* All others */
#define TIME_T_MAX      (~(time_t)0 - TIME_T_MIN)
#endif /* __TURBOC__ */
#endif /* TIME_T_MAX */

I contacted the antiword author and he suggests I find an alternative method to derive the min/max values for time_t.

What is a cross-platform method of calculating the min/max value of time_t if you are unsure what the underlying type is?

Jeroen Ooms
  • 31,998
  • 35
  • 134
  • 207
  • I don't think there is a universal method, as the standard is not specifying *anything* about the underlying type. There are plenty of duplicates by the way. – Eugene Sh. Apr 28 '17 at 13:46
  • Possible duplicate of [What primitive data type is time\_t?](http://stackoverflow.com/questions/2792551/what-primitive-data-type-is-time-t) – Badda Apr 28 '17 at 13:49
  • OMG that's an old piece of software! I vaguely remember running it in Linux way back when. Also cool to see the RISC OS section state that Antiword "is 26/32 bit neutral". :) I think the best bet is to dive in and figure out *why* it wants to have the minimum value for a time, and perhaps refactor that. – unwind Apr 28 '17 at 13:58
  • Do you want the min/max _representable_ value for the data type of `time_t` or the min/max _valid_ value? Example, `time_t` may be `long`, yet any value less than 0 _may_ not correspond to a valid time. By _valid_ I mean returnable from `time()` or usable with `mktime()`, etc. – chux - Reinstate Monica Apr 28 '17 at 15:10

1 Answers1

4

C11's _Generic macro allows one to return min/max values of integral types:

#  define variable_min_value(_var)          \
    _Generic(_var,                  \
         char: CHAR_MIN,            \
         unsigned char: (unsigned char)0,   \
         signed char: SCHAR_MIN,        \
         signed short: SHRT_MIN,        \
         unsigned short: (unsigned short)0, \
         signed int: INT_MIN,           \
         unsigned int: 0u,          \
         signed long: LONG_MIN,         \
         unsigned long: 0ul,            \
         signed long long: LLONG_MIN,       \
         unsigned long long: 0ull)

#define TIME_T_MIN   (variable_min_value((time_t)0))

See this library for other variants.

psmears
  • 26,070
  • 4
  • 40
  • 48
ensc
  • 6,704
  • 14
  • 22
  • 1
    This is great. Note that the dupe-suggestion mentions that it might be floating-point, too. – unwind Apr 28 '17 at 14:44
  • Suggest extending this good answer to include `float, double, long double` as `time_t` is specified as a scalar - it could be FP. Also a `default:` that is a compiler error may be useful. – chux - Reinstate Monica Apr 28 '17 at 15:13