我知道size_t是无符号的,因此不允许使用负值,time_t是我所知道的最好的签名,因此我可以将-1分配给size_t。但是,对于time_t,我并不完全确定。如果我通过头文件遵循定义,我最终会在这里:
typedef __time_t time_t;
,然后在这里:
__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
最后
#define __TIME_T_TYPE __SYSCALL_SLONG_TYPE
我不太确定 __ SYSCALL_SLONG_TYPE 是什么,但我猜这是签名长。不幸的是,即使在执行此跟踪之后,我也只能希望其他c ++ 11平台具有相同的实现。我仍然不确定这对所有人来说都是合法且明确的:
size_t foo = -1;
当然,将time_t签名是有意义的,因为可以有负时间偏移,例如模拟时区。但另一方面,让它无符号是有道理的,因为在1970年之后需要花费很多时间来计算。所以常识是两种方式:) googling on time_t返回了这个:
"由于历史原因,它通常被实现为表示自UTC时间1970年1月1日00:00(即,unix时间戳)以来经过的秒数的整数值。虽然库可以使用替代时间表示来实现此类型。"
来源:http://www.cplusplus.com/reference/ctime/time_t/
并在同一页面上:"便携式程序不应直接使用此类型的值,但始终依赖于对标准库元素的调用将它们转换为可移植类型。"
所以time_t在所有系统上都没有明确定义,但是,time()返回time_t:所以我不会是第一个在界面中导出它的人。我应该使用哪种其他类型?
我问这两个原因:
问题:由于time_t不是所有平台上明确定义的时间表示,因此我可以使用哪种数据类型(1)快速和(2)可比较便携?< / p>
例如,关于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;
}
所有平台上的time_t都会无污染吗?
答案 0 :(得分:4)
(time_t)(-1)
已经意味着“这不是一个有效的时间”,无论time_t
实际是什么。标准函数mktime
会在出错时返回此值,您也可以。
C和C ++标准对time_t
中的时间编码没有任何说明。标准函数difftime
以double
计算时间差,以time_t
表示,两次表示为time_t
,这是按时间顺序排序time_t
值的唯一有福方式。但是,POSIX标准指定time_t
是以秒为单位的时间,因此在POSIX系统上,可以直接将<
与time_t
进行比较。
请注意,C和POSIX都允许{{1}}为任何算术类型(不仅仅是整数)。
答案 1 :(得分:1)
如果您需要保证在不同平台之间移植的时间表示,则需要使用或创建一个库来处理您使用的平台之间的差异。
例如Boost.Date_Time,您可以选择它支持的任何表示形式。您甚至可以以独立于平台的方式使用seconds elapsed since epoch(在boost支持的所有平台上)。
答案 2 :(得分:0)
我已经沉迷于optional
(通过提升,或根据C ++ 1y tr工作文件推出自己的推文)。
optional<foo>
是foo
或nullopt
。您通过dereerence访问foo
,但数据通过联合存储在optional
中。我懒惰的实现使用了一个指针,它是foo
还是不是&#34;因为这会使调试变得微不足道。
它比标志值更好地传达故障,并在我写的代码中替换了一堆基于指针的标记。