_argptr woes -- RFC from Walter
kris
foo at bar.com
Sat Mar 17 12:57:58 PDT 2007
Frits van Bommel wrote:
> kris wrote:
>
>> Frits van Bommel wrote:
>>
>>>>>> kris wrote:
>>>>>>
>>>>>>> The D spec says:
>>>>>>>
>>>>>>> "The implementiations of these variadic functions have a special
>>>>>>> local variable declared for them, _argptr, which is a void*
>>>>>>> pointer to the first of the variadic arguments. To access the
>>>>>>> arguments, _argptr must be cast to a pointer to the expected
>>>>>>> argument type"
>>>>>>>
>>>>>>>
>>>>>>> To me, this means that a D compiler must implement _argptr in
>>>>>>> these terms. Is that indeed the case, Walter? Or is my
>>>>>>> interpretation incorrect?
>>
>> [snip]
>>
>>> [2]: At least, I presume this discussion was brought on by the
>>> non-portable code in tango.text.convert.Layout?
>>
>>
>> Indeed, although non-portable holds true only if you think in C
>> instead of D. According to the D documentation that code is written
>> "correctly", and thus it ought to be portable.
>
>
> Assuming _argptr is a pointer and dereferencing it may be according to
> the spec as it is currently written, but that's not all the code does.
> It also *increments* the pointer, at which time it _assumes_ all
> arguments are aligned at a multiple of int.sizeof (4). Even if varargs
> were entirely stack-based, that would likely break in the case of amd64
> since the most natural alignment for most parameters would be 8 (aka
> size_t.sizeof and (void*).sizeof). That's the size of anything a 'push'
> pushes and anything a 'pop' pops, as well as the size of return
> addresses. This could be 'fixed' for this case by using size_t or void*,
> but even that isn't guaranteed to work anywhere else.
> Note that incrementing _argptr manually is discouraged:
> "To protect against the vagaries of stack layouts on different CPU
> architectures, use std.stdarg to access the variadic arguments"
> Nowhere on that page (that I can see) is the minimum alignment for
> arguments specified.
> So even given that dereferencing the pointer may be portable, there's no
> way to portably increment it without using va_arg.
> In fact, AFAICT it's not even guaranteed you need increment instead of
> decrement to get to the next argument (other than considerable
> difficulties / impossibility of implementing va_arg for that case).
>
> So even though GDC may be going against the spec here, I'm still pretty
> sure that piece of code is not portable.
That's why "correctly" was quoted, Frits. I think you'll find a similar
concern in the Phobos stdarg? There's a couple of issues going on here,
and it would be useful to tease them apart first. Let's at least figure
out if the D doc is correct first, before we get all pedantic? :)
More information about the Digitalmars-d
mailing list