Turbo C ++:为什么printf在没有传递变量的情况下打印期望值?

时间:2013-08-22 19:26:28

标签: c printf undefined-behavior turbo-c

在多项选择测试中提出了一个问题:以下程序的输出是什么:

#include <stdio.h>

int main(void)
{
    int a = 10, b = 5, c = 2;

    printf("%d %d %d\n");

    return 0;
}

并且选择是10,5和2的各种排列。出于某种原因,它适用于我们在大学时使用的Turbo C ++。但是,在使用gcc(在启用-Wall时发出警告)或clang(启用了-Wformat并在默认情况下发出警告)或在Visual C ++中编译时,它不会。正如预期的那样,输出是垃圾值。我的猜测是它与Turbo C ++是16位,在32位Windows XP上运行这一事实有关,或者TCC在标准方面很糟糕。

5 个答案:

答案 0 :(得分:20)

代码有undefined behaviour

在Turbo C ++中,碰巧三个变量位于堆栈上缺少printf()参数的确切位置。这会导致未定义的行为通过打印“正确”值来表现。

但是,你不能合理地依赖于这种情况。即使对构建环境稍有改动(例如,不同的编译器选项),也可能以任意恶劣的方式破坏事物。

答案 1 :(得分:4)

这是undefined behaviour。所以它可以是任何东西。

尝试使用

printf("%d %d%d", a,b,c)

原因: - 在堆栈上调用局部变量,Turbo C ++中的printf看到它们的顺序与它们在堆栈中的分配顺序相同。

建议(来自评论): -

了解特定编译器以特定方式运行的原因在诊断问题时非常有用,但不要对信息进行任何其他用途。

答案 2 :(得分:4)

这里的答案是程序可以做任何事情 - 这是未定义的行为。根据{{​​1}}的文件(强调我的):

  

默认情况下,参数按给定的顺序使用,其中每个'*'和每个转换说明符要求下一个参数(如果给出的参数不够多,则会出错)

如果您的多项选择测试没有选择“未定义的行为”,那么这是一个有缺陷的测试。在未定义行为的影响下,任何在这样的多项选择题测试中的答案在技术上是正确的。

答案 3 :(得分:3)

实际上发生的是参数通常在调用堆栈上传递。局部变量在调用堆栈上传递,因此printf()可以看到这些值,编译器决定将它们存储在那里。

这种行为以及许多其他行为都是在 undefined behavoir

的保护下允许的。

答案 4 :(得分:2)

不,它与架构无关。它与TurboC ++如何处理堆栈有关。变量abc是本地人,因此在堆栈中分配。 printf也期望堆栈中的值。显然,在本地人和printf能够将它们作为参数后,TurboC ++不会向堆栈添加任何其他内容。只是巧合。