2

I have a time_t type variable (from <time.h>) that stores the time of a failure, and would like to initialize it to a "null" value that will be the final value if no error occurs. Is there a standard way to set a time_t variable to some kind of known null value? I see that the time() function returns -1 if an error occurs, maybe this is best, but wonder if I can just assign an integer value to a typedef like that. Maybe I'd need to use this...?

time_t failTime = (time_t)(-1);

robisrob
  • 940
  • 12
  • 23
  • 2
    The accepted answer here http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to indicates "ISO C defines time_t as an arithmetic type, but does not specify any particular type, range, resolution, or encoding for it. Also unspecified are the meanings of arithmetic operations applied to time values." So it sounds like it'll be nonstandard, whatever your solution is. – Topological Sort Mar 03 '17 at 16:43
  • 3
    `time_t failTime = -1;` is sufficient unless code is attempting to work with other negative values of `time_t` - which is somewhat rare. – chux - Reinstate Monica Mar 03 '17 at 16:44
  • I suppose there is no reason to cast an integer literal – robisrob Mar 03 '17 at 16:49
  • @robisrob A _potential_ reason to cast is to match the C spec's usage of `(time_t)(-1)`. AFIAK, a system _could_ use `unsigned long long` as `time_t` and then the cast is needed to quiet a pedantic warning of assigning a signed value to an unsigned variable. – chux - Reinstate Monica Mar 03 '17 at 17:02
  • What do you mena with "NULL" value? `NULL` is a macro with a null pointer constant. Nothing you want to assign to a `time_t`. – too honest for this site Mar 03 '17 at 17:24
  • @olaf the quoted "NULL" in this post does not imply `NULL`, a _null pointer constant_, but a default illegal value that `time_t`, hopefully, does not use. It is a subtle implication, easy to confuse with a literal first pass reading. – chux - Reinstate Monica Mar 03 '17 at 17:30
  • @chux: Looks like one more XY problem to me. – too honest for this site Mar 03 '17 at 17:31
  • @Olaf Unless the answer is [42](https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life.2C_the_Universe.2C_and_Everything_.2842.29), all questions are XY problems.. ;-) – chux - Reinstate Monica Mar 03 '17 at 17:33
  • There seems to be some confusion on whether Posix requires `time_t` to be signed. In addition, while the C++ spec says that `time` returns `(time_t)(-1)` on error, the Gnu C library docs say that `time` can't fail. I think it probably makes more sense to set your 'uninitialised' value as 0, not -1. Presumably your code can't record a failure that occurred in 1970, so what's the point of saying that "null" is one second before the epoch, rather than exactly at the epoch? – EML Sep 02 '23 at 09:52

2 Answers2

7

As OP referred, the result from a failed time() (and other standard C library functions) is (time_t)(-1), so it is at least reasonable to initialize time_t to that "fail" value.

// Just like OP
time_t failTime = (time_t)(-1);

time_t is a real type and "integer and real floating types are collectively called real types" . time_t could be a double, long, etc.

Strictly speaking time_t could encode a valid time as (time_t)(-1), yet that is not distinguishable from an error return for various functions.

Given the wide latitude of possible encoding and considering common practice to use integer seconds since Jan 1, 1970, (time_t)(-1) is a reasonable choice.

A more robust (or pedantic solution) would pair a flag with the time variable to indicate its correctness. Example:

struct time_pedantic {
  time_t t;
  bool valid;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
3

If you're stuck with needing something that depends on nothing but the basic C language, your best bet is to choose a time far in the past that you don't actually need to represent, set it up in a struct tm, and convert to time_t with mktime. You might have to loop and retry until you find a value that converts successfully. Typical systems have a range of representable times of around +/- 68 years centered at 1970, but you can't necessarily assume yours does.

If you're on a POSIX or POSIX-like implementation, on the other hand, you can assume time_t is an arithmetic type representing pseudo-UTC (more like UT1 or "cloud-UTC" as I call it) seconds since the beginning of 1970. Then you can just choose a large negative integer value in the range of the time_t type.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711