digitalmars.D - _argptr layout
- Iain Buclaw (48/48) Jan 16 2011 I guess I've always assumed it to be all values packed together and acce...
I guess I've always assumed it to be all values packed together and accessible via moving the pointer forwards/backwards (like 32bit varargs), but is this really true? Are all datatypes really expected to be a packed data structure? Or are all varargs in D the exact same underpinnings as the C ABI for the platform you're running on, but just encapsulated in a void*. std.format is a prime example of this being the former, and the whole of tango assumes so too (regardless of platform/architecture). The documentation tends to agree with the former too, but is somewhat vague: '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.' But other than that, there's nothing else describing it. I know it can't be passed as an argument, I know that it's only available for extern(D) linkage. But what is it supposed to be? This comes at a time where I'm sorting this out on gdc, see here for an idea of the way I've done it: http://d.puremagic.com/issues/show_bug.cgi?id=670#c7 However there are quite a number of problems in phobos. For example, in std.stream (a very condensed showing, comments are my own): import std.stdarg; // for extern(D) linkage. va_list is a void* size_t vprintf(const(char)[] format, va_list args) { char[1024] buffer; char* p = buffer.ptr; auto f = toStringz(format); size_t psize = buffer.length; size_t count; while (true) { // calls extern(C) function vsnprintf that expects 'args' // to be that of the target-specific type. Which could be char*, // struct[1], or a ubyte[12][1]. However, we have void* ... count = vsnprintf(p, psize, f, args); if (count == -1) psize *= 2; else if (count >= psize) psize = count + 1; else break; p = cast(char*) alloca(psize); } writeString(p[0 .. count]); return count; } It's rather bad enough that phobos rather dumbly assumes 32bit anyway. And 64bit users have always complained that they can't do *cast(int*)_argptr in gdc. So what exactly am I implementing here? I've actually had a good sit back from it all for reflection and have only come up with the answer: 'You know, I honestly don't know'. Just need some clarification. :) Regards
Jan 16 2011