如果使用错误的格式string调用printf,会发生什么情况?

换句话说:错误的printf / fprintf十进制整数( %d%u%ld%lld )格式string会导致程序崩溃或导致未定义的行为?

Cosinder按照以下代码行:

 #include <iostream> #include <cstdio> int main() { std::cout << sizeof(int) << std::endl << sizeof(long) << std::endl; long a = 10; long b = 20; std::printf("%d, %d\n", a, b); return 0; } 

结果在32位架构上:

 4 4 10, 20 

64位体系结构上的结果:

 4 8 10, 20 

在任何情况下程序打印预期的结果。 我知道,如果long值超出int范围,程序就会输出错误的数字 – 这很丑,但是不会影响程序的主要目的 – 但是除此之外,有没有什么意外的事情发生?

如果使用错误的格式string调用printf,会发生什么情况?

任何事情都可能发生。 这是未定义的行为!
未定义的行为意味着任何事情都可能发生。 它可能会显示您期望的结果,或者它可能不会或可能会崩溃。 任何事情都可能发生,除了你自己,你可以责怪任何人。

参考:

c99标准:7.19.6.1:
第9段:

如果转换规范无效,则行为是不确定的。 225)如果任何参数不是相应覆盖规范的正确types,则行为是不确定的。

哦,是的 – printf取决于格式string来确定接下来要获取的variables的大小和types。 当格式string错误时,它可能会尝试获取一个甚至不存在的variables,并带来所有后果。

这是未定义的行为 – 规范中没有任何内容告诉编译器devise者(或C库devise者)应该如何处理,因此他们被允许做任何事情。

在实践中,这完全取决于数字的解释,最有可能的是,你从来不会得到任何好的东西。 真正糟糕的是当你把string和整数格式混合在一起时 – string将很好地打印成(可能是奇怪的)数字,但是当string传递时数字不太可能“工作” – 因为string是指向第一个字符 – 而且大多数数字在典型系统中都不是有效的指针,所以会崩溃。

但是没有任何保证。 在你的64位示例中,显然这个数字是“little endian”。 尝试与0x100000000相同的事情,它会打印0 – 因为数字的其余部分丢失。

如果使用错误的格式string调用printf,则会发生任何情况。 它的未定义的行为,不应该依赖未定义的行为。

不要使用printf

printf是C天的遗留物,不再需要…使用std::cout和I / O操纵符。