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

在多项选择测试中提出了一个问题:以下程序的输出结果如何:

#include  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在标准方面很糟糕。

代码具有未定义的行为 。

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

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

这里的答案是程序可以做任何事情 – 这是未定义的行为。 根据printf()的文档(强调我的):

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

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

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

尝试使用

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

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

建议(来自评论): –

了解它为什么以特定方式使用特定编译器行为可以用于诊断问题,但不要对信息进行任何其他使用。

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

这种行为以及许多其他行为都是在未定义的行为范围内允许的

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