为什么 `std::time` 有一个不必要的参数?
Why does `std::time` have an unnecessary parameter?
来自cppref:
std::time_t time(std::time_t* arg);
Returns the current calendar time encoded as a std::time_t
object, and also stores it in the object
pointed to by arg
, unless arg
is a null pointer.
我从未见过有人用非空指针参数调用 std::time
。我只是想知道:
1.为什么 std::time
有一个不必要的参数?
2。设计背后有没有motivation/rationale
历史上 time_t
是一个抽象类型,并且可能期望它可能需要是一个可能无法可靠返回的结构或扩展类型,或者编译器可能在 ABI 中不同意返回它,这样通过将它存储到调用者提供的地址 "made sense" 来返回它。请注意 difftime
接口的存在以及 C 关于如何解释 time_t
值的模糊性。只有POSIX(很久以后)要求单位是秒(从纪元开始,并定义了纪元)。我不确定是否有任何具体证据证明这是动机(也许在 C89 基本原理文档中?)但这是我要研究的领域。
对于C++来说,简单来说就是std::time
接口就是Ctime
函数,包裹在std::
.
中
[此答案改编自very similar answer to a slightly different question。]
std::time()
有一个“额外参数”,因为它与 C 的 time()
函数相同,后者非常非常古老。它可以追溯到 C 的诞生之初,当时该语言甚至没有类型 long
。曾几何时,获得类似 32 位类型的唯一方法是使用两个 int
s 的数组——那时 int
s 是 16 位。
所以你打电话给
int now[2];
time(now);
和time
将32位的时间分别填充到now[0]
和now[1]
中,一次16位。如果你想以人类可读的格式打印时间,你调用 ctime(int *)
,它也接受时间作为指针,原因基本相同。
稍后,dmr 完成了向编译器添加 long
,所以你可以开始说
long now;
time(&now);
大约在同一时间,有人意识到如果 time()
继续并 return 编辑值会很有用,现在可以了,而不是仅仅通过指针填充它.但是——向后兼容是一件很棒的事情——为了所有仍在执行 time(&now)
的代码的利益,time()
函数必须继续支持指针参数。这就是为什么 - 这就是为什么向后兼容并不总是那么美妙的事情,毕竟 - 如果你使用 return 值,你仍然必须将 NULL 作为指针传递:
long now = time(NULL);
后来,我们开始多次使用 time_t
而不是普通的 long
,例如,它可以更改为 64 位类型,避开 y2.038k problem.
所以,综上所述,“多余的论据”是历史遗留物,是time()
无法简单return那个时代遗留下来的,因为没有合适的return 类型。此外,额外的参数必须是一个指向要填充的数据结构的指针,因为该数据结构——一个数组——也不能简单地由一个函数return编辑。
来自cppref:
std::time_t time(std::time_t* arg);
Returns the current calendar time encoded as a
std::time_t
object, and also stores it in the object pointed to byarg
, unlessarg
is a null pointer.
我从未见过有人用非空指针参数调用 std::time
。我只是想知道:
1.为什么 std::time
有一个不必要的参数?
2。设计背后有没有motivation/rationale
历史上 time_t
是一个抽象类型,并且可能期望它可能需要是一个可能无法可靠返回的结构或扩展类型,或者编译器可能在 ABI 中不同意返回它,这样通过将它存储到调用者提供的地址 "made sense" 来返回它。请注意 difftime
接口的存在以及 C 关于如何解释 time_t
值的模糊性。只有POSIX(很久以后)要求单位是秒(从纪元开始,并定义了纪元)。我不确定是否有任何具体证据证明这是动机(也许在 C89 基本原理文档中?)但这是我要研究的领域。
对于C++来说,简单来说就是std::time
接口就是Ctime
函数,包裹在std::
.
[此答案改编自very similar answer to a slightly different question。]
std::time()
有一个“额外参数”,因为它与 C 的 time()
函数相同,后者非常非常古老。它可以追溯到 C 的诞生之初,当时该语言甚至没有类型 long
。曾几何时,获得类似 32 位类型的唯一方法是使用两个 int
s 的数组——那时 int
s 是 16 位。
所以你打电话给
int now[2];
time(now);
和time
将32位的时间分别填充到now[0]
和now[1]
中,一次16位。如果你想以人类可读的格式打印时间,你调用 ctime(int *)
,它也接受时间作为指针,原因基本相同。
稍后,dmr 完成了向编译器添加 long
,所以你可以开始说
long now;
time(&now);
大约在同一时间,有人意识到如果 time()
继续并 return 编辑值会很有用,现在可以了,而不是仅仅通过指针填充它.但是——向后兼容是一件很棒的事情——为了所有仍在执行 time(&now)
的代码的利益,time()
函数必须继续支持指针参数。这就是为什么 - 这就是为什么向后兼容并不总是那么美妙的事情,毕竟 - 如果你使用 return 值,你仍然必须将 NULL 作为指针传递:
long now = time(NULL);
后来,我们开始多次使用 time_t
而不是普通的 long
,例如,它可以更改为 64 位类型,避开 y2.038k problem.
所以,综上所述,“多余的论据”是历史遗留物,是time()
无法简单return那个时代遗留下来的,因为没有合适的return 类型。此外,额外的参数必须是一个指向要填充的数据结构的指针,因为该数据结构——一个数组——也不能简单地由一个函数return编辑。