I know that size_t is unsigned and hence negative values are not allowed, time_t is to the best of my knowledge signed, so I am allowed to assign -1 to a size_t. However, for time_t I'm not entirely sure. If I follow the definition through the header files I end up here:
typedef __time_t time_t;
, then here:
__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
and finally
#define __TIME_T_TYPE __SYSCALL_SLONG_TYPE
I'm not too sure what a __SYSCALL_SLONG_TYPE is, but I guess it is a signed long. Unfortunately, even after doing this trace, I can only hope that other c++11 platforms have the same implementation. I'm still not sure that this will be legal and well-defined for all of them:
size_t foo = -1;
Of course it makes sense to make a time_t signed, since one can have negative time offsets, for example to model time zones. But on the other hand it makes sense to have it unsigned, because there are a lot of seconds to count after 1970. So common sense goes both ways :) Googling on time_t returned this:
"For historical reasons, it is generally implemented as an integral value representing the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC (i.e., a unix timestamp). Although libraries may implement this type using alternative time representations."
Source: http://www.cplusplus.com/reference/ctime/time_t/
and on the same page: "Portable programs should not use values of this type directly, but always rely on calls to elements of the standard library to translate them to portable types."
So time_t is not at all well-defined on all systems, however, time() returns a time_t: so I wouldn't be the first to export it in an interface. What other type should I use?
I'm asking for these two reasons:
- Speed: Using a struct, like struct tm is slow, as it has more bytes and hence copying it or comparing it with another struct tm will be slower than doing the same with a long.
- Ordering: I want to have a fast data type for dates, which allows me to do a < b to figure out which of the dates a and b comes first.
Question: Since time_t is not a well-defined time representation on all platforms, what kind of data type that is (1) fast and (2) comparable can I use that is portable?
For example, regarding the ordering of time_t:
#include <iostream>
#include <ctime>
#include <cstring>
int main() {
struct tm tm_a, tm_b;
memset(&tm_a, 0, sizeof(struct tm));
memset(&tm_b, 0, sizeof(struct tm));
if(strptime("2014-01-01 12:00:00", "%Y-%m-%d %H:%M:%s", &tm_a) && strptime("2014-01-01 11:59:59", "%Y-%m-%d %H:%M:%s", &tm_b)) {
if(mktime(&tm_a) > mktime(&tm_b)) std::cout << "time_t ordering OK." << std::endl;
else std::cout << "time_t ordering tainted" << std::endl;
} else std::cout << "failed to parse time" << std::endl;
return 0;
}
Will time_t be untainted on all platforms?