如果使用错误的格式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操纵符。