我有以下代码。
#include <stdio.h>
#include <time.h>
int main ()
{
time_t rawtime;
time_t t2 = rawtime;
if(rawtime == t2) printf("Hi %ul %ul\n", rawtime, t2);
return(0);
}
运行此代码时,printf为rawtime和t2提供不同的答案。这是为什么?有人可以帮忙吗?
答案 0 :(得分:2)
您正在访问未初始化的变量。这是未定义的行为。
为什么它在不同的执行中有所不同。我特别困惑,因为条件“(rawtime == t2)”是真的。
当调用未定义的行为时,为什么没有任何问题。变量已经声明,因此在内存中占有一席之地。该位置可能包含先前程序执行的垃圾值或任何其他值。也许某些共同事件的值对于这两个变量是相同的,因此if()
条件将变为True
。
但是所有这些事情在一方面,当它调用未定义的行为时,不能质疑程序或语句的流程,因为问题是在标准中查询,而当标准本身没有定义它时,将在何处任何人都可以从中得到解释。
答案 1 :(得分:2)
这就是为什么他们不能比较相同的原因:
rawtime
未初始化。
t2
初始化或不是。
如果初始化t2
,那么我们将初始化值与未初始化值进行比较。没有理由期望这些比较相等。
如果t2
未初始化,我们会比较两个未初始化的变量。没有理由期望这些比较为平等
无论哪种方式,都没有理由期望这些比较相等。
要期望它们相等,你必须为t2
发明一些奇怪的状态,我甚至不知道是什么,初始化为未指定的值?未初始化但保证比较等于另一个未初始化的值?或者是什么?
无论思维过程如何导致您将这些过程视为平等,我都无法理解。
顺便说一下,试图从C标准中收集这一点是非常困难的。它来自一个非常模糊的规则 - “如果左值指定了一个自动存储持续时间的对象,可以使用寄存器存储类声明(从未使用过地址),并且该对象未初始化(未使用初始化程序声明在使用之前没有对它进行任何分配),行为是未定义的。“
更容易理解它实际上是未初始化的,而不是试图理解复杂的规则,以确保它何时具有未指定的值,何时不是。您必须了解陷阱表示和其他复杂性。
答案 2 :(得分:2)
一方面,是的,由于rawtime
未初始化,行为未定义,所有投注均已关闭。对于所有的标准护理,恶魔可能会飞出你的计算机的鼻子。
但另一方面,rawtime
只是一个整数。也许64位,可能是32位。有2 32 或2 64 普通值。没有陷阱表示(在您可能正在使用的任何计算机上。)因此,rawtime
中开始的任何随机值都会被复制到t2
。因此他们几乎必须比较相等,所以printf
几乎必须被调用。好吧到目前为止。
因此,如果printf
因rawtime
和t2
相等而被调用,那么它们如何打印为不相等?可能是因为您不小心使用了%ul
而不是%lu
。您的两个格式说明符可能是打印rawtime
的上半部分和下半部分(可能不相等)而根本不打印t2
。尝试将%ul
更改为%lu
,看看会发生什么。
[免责声明。这是一个现实世界的答案,而不是一个标准的答案。如果你只看标准,那么在它的行为变得不确定之后询问程序的作用确实毫无意义。现在有一些编译器可以让你自己做一些非常奇怪的事情,当你的程序未定义并且他们被允许时。很难想象编译器会发出代码(a)复制一个位模式然后(b1)比较它不等或(b2)比较它相等但打印它不相等,但它是不完全不可能。)