Pet*_*ica 3 c c++ printf undefined-behavior
在C(n1570 7.21.6.1/10)和C++(通过包含C标准库)中,未定义的行为是为printf提供其类型与其转换规范不匹配的参数.一个简单的例子:
printf("%d", 1.9)
Run Code Online (Sandbox Code Playgroud)
格式字符串指定int,而参数是浮点类型.
这个问题的灵感来自于一个用户遇到遗留代码的问题,这些代码存在大量的转换不匹配,这显然没有任何损害,参见 理论和实践中未定义的行为.
声称格式不匹配UB起初看起来很激烈.很明显,输出可能是错误的,具体取决于精确的不匹配,参数类型,字节序,可能的堆栈布局和其他问题.正如一位评论员指出的那样,这也延伸到后来的(甚至是之前的?)论点.但这远不是一般的UB.就个人而言,除了预期的错误输出外,我从未遇到任何其他问题
冒险猜测,我会排除对齐问题.我可以想象的是,提供一个格式字符串,使得printf期望大数据和小的实际参数可能让printf读取超出堆栈,但我缺乏对var args机制和特定printf实现细节的深入了解来验证.
我快速浏览了printf源代码,但它们对于休闲读者来说非常不透明.
因此我的问题是:错误匹配转换说明符和printf使其成为UB的参数有哪些具体危险?
Jon*_*ely 11
printf只有正确使用它才能按标准描述的方式工作.如果使用不正确,则行为未定义.为什么标准定义了当你使用它时会发生什么?
具体来说,在某些体系结构上,浮点参数在不同的寄存器中传递给整数参数,因此printf当它试图找到int匹配的格式说明符时,它会在相应的寄存器中找到垃圾.由于这些细节超出了标准的范围,因此没有办法处理这种不当行为,除非说它未定义.
有关它可能出错的一个例子,使用格式说明符"%p"但传递浮点类型可能意味着printf尝试从寄存器或堆栈位置读取指针,该指针尚未设置为有效值并且可能包含陷阱表示,这将导致程序中止.