为什么以下代码给出不同的答案?

时间:2016-01-27 03:32:40

标签: c

我有以下代码。

#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提供不同的答案。这是为什么?有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

您正在访问未初始化的变量。这是未定义的行为。

为什么它在不同的执行中有所不同。我特别困惑,因为条件“(rawtime == t2)”是真的。

当调用未定义的行为时,为什么没有任何问题。变量已经声明,因此在内存中占有一席之地。该位置可能包含先前程序执行的垃圾值或任何其他值。也许某些共同事件的值对于这两个变量是相同的,因此if()条件将变为True

但是所有这些事情在一方面,当它调用未定义的行为时,不能质疑程序或语句的流程,因为问题是在标准中查询,而当标准本身没有定义它时,将在何处任何人都可以从中得到解释。

答案 1 :(得分:2)

这就是为什么他们不能比较相同的原因:

  1. rawtime未初始化。

  2. t2初始化或不是。

  3. 如果初始化t2,那么我们将初始化值与未初始化值进行比较。没有理由期望这些比较相等。

  4. 如果t2未初始化,我们会比较两个未初始化的变量。没有理由期望这些比较为平等

  5. 无论哪种方式,都没有理由期望这些比较相等。

  6. 要期望它们相等,你必须为t2发明一些奇怪的状态,我甚至不知道是什么,初始化为未指定的值?未初始化但保证比较等于另一个未初始化的值?或者是什么?

    无论思维过程如何导致您将这些过程视为平等,我都无法理解。

    顺便说一下,试图从C标准中收集这一点是非常困难的。它来自一个非常模糊的规则 - “如果左值指定了一个自动存储持续时间的对象,可以使用寄存器存储类声明(从未使用过地址),并且该对象未初始化(未使用初始化程序声明在使用之前没有对它进行任何分配),行为是未定义的。“

    更容易理解它实际上是未初始化的,而不是试图理解复杂的规则,以确保它何时具有未指定的值,何时不是。您必须了解陷阱表示和其他复杂性。

答案 2 :(得分:2)

一方面,是的,由于rawtime未初始化,行为未定义,所有投注均已关闭。对于所有的标准护理,恶魔可能会飞出你的计算机的鼻子。

但另一方面,rawtime只是一个整数。也许64位,可能是32位。有2 32 或2 64 普通值。没有陷阱表示(在您可能正在使用的任何计算机上。)因此,rawtime中开始的任何随机值都会被复制到t2。因此他们几乎必须比较相等,所以printf几乎必须被调用。好吧到目前为止。

因此,如果printfrawtimet2相等而被调用,那么它们如何打印为不相等?可能是因为您不小心使用了%ul而不是%lu。您的两个格式说明符可能是打印rawtime的上半部分和下半部分(可能不相等)而根本不打印t2。尝试将%ul更改为%lu,看看会发生什么。

[免责声明。这是一个现实世界的答案,而不是一个标准的答案。如果你只看标准,那么在它的行为变得不确定之后询问程序的作用确实毫无意义。现在有一些编译器可以让你自己做一些非常奇怪的事情,当你的程序未定义并且他们被允许时。很难想象编译器会发出代码(a)复制一个位模式然后(b1)比较它不等或(b2)比较它相等但打印它不相等,但它是不完全不可能。)