On Sat, Jun 5, 2010 at 9:31 PM, vefatica <> wrote:
> OK, that makes sense. What do you suppose happens when an arg is 64-bits
> (say
> ULONGLONG) and the format is "%I64u"? ... a 32-bit pointer is pushed (and
> Sprintf acts as if it's getting a pointer)?
>
I don't believe that Sprintf dereferences any pointers unless %s is passed
in.
First, I the C standard allows for considerable lattitude in exactly what
happens in the details, but imposes requirements on the results, so my
statements here apply to the Microsoft compilers that I'm familiar with.
Certainly don't fall into the trap and expect Sprintf("%u %u", func1(),
func2()) will actually call either function before the other -- that is
specifically left implementation defined. Some compilers and/or switches
will pass things in registers instead of on a stack in cases as well.
Specific knowledge in this case is only of academic interest and the
standard requires that code does not rely on it.
Ok, on to the answer.
It pushes 64 bits in that case. If you have a 64-bit var v64 and do
Sprintf("%08lX%08lX %016I64X", v64, v64) you'll see the same result in both
cases. I've done this in my 16-bit compiler which was unaware of 64-bit
quantities and I had to simulate them.
To be portable, Sprintf and the family use the va_list / va_arg mechanism,
which simply index into the stack to get their arguments. I've written
plenty of routines that use that myself. va_list returns a pointer into
stack memory where the first argument was pushed. Using va_arg dereferences
that pointer after typecasting to what you said you were expecting, then
advances the pointer by the right amount, which is almost always 4 in this
compiler, but may be larger for ULONGLONG or double or directly pushed
structures (as opposed to a pointer to a structure).
--
Jim Cook
2010 Sundays: 4/4, 6/6, 8/8, 10/10, 12/12 and 5/9, 9/5, 7/11, 11/7.
Next year they're Monday.