title: Why are arguments which do not match the conversion specifier in printf undefined behavior?
body: <p>In both C (n1570 7.21.6.1/10) and C++ (by inclusion of the C standard library) it is undefined behavior to provide an argument to printf whose type does not match its conversion specification. A simple example:</p>
  
  <pre><code>printf("%d", 1.9)
  </code></pre>
  
  <p>The format string specifies an int, while the argument is a floating point type. </p>
  
  <p>This question is inspired by the question of a user who encountered legacy code with an abundance of conversion mismatches which apparently did no harm, cf. <a href="https://stackoverflow.com/q/33647458/3150802">undefined behaviour in theory and in practice</a>.</p>
  
  <p>Declaring a mere format mismatch UB seems drastic at first. It is clear that the <em>output</em> can be wrong, depending on things like the exact mismatch, argument types, endianness, possibly stack layout and other issues. This extends, as one commentator there pointed out, also to subsequent (or even previous?) arguments. But that is far from general UB. Personally, I never encountered anything else but the expected wrong output.</p>
  
  <p>To venture a guess, I would exclude alignment issues. What I can imagine is that providing a format string which makes printf expect large data together with small actual arguments possibly lets <code>printf</code> read beyond the stack, but I lack deeper insight in the var args mechanism and specific printf implementation details to verify that. </p>
  
  <p>I had a quick look at the <a href="https://sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/vfprintf.c;h=fc370e8cbc4e9652a2ed377b1c6f2324f15b1bf9;hb=3321010338384ecdc6633a8b032bb0ed6aa9b19a" rel="nofollow noreferrer">printf sources</a>, but they are pretty opaque to the casual reader. </p>
  
  <p>Therefore my question: What are the specific dangers of mis-matching conversion specifiers and arguments in <code>printf</code> which make it UB?</p>