_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