digitalmars.D.bugs - [Issue 5494] New: [patch,enh] Issues with std.stdarg
- d-bugmail puremagic.com (92/92) Jan 26 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5494
- d-bugmail puremagic.com (11/11) Feb 07 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5494
- d-bugmail puremagic.com (11/11) Feb 07 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5494
http://d.puremagic.com/issues/show_bug.cgi?id=5494 Summary: [patch,enh] Issues with std.stdarg Product: D Version: D2 Platform: Other OS/Version: Windows Status: NEW Keywords: patch Severity: enhancement Priority: P3 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: sandford jhu.edu Currently, std.stdarg doesn't appear to be 64-bit safe (see Issue 4310) is extremely limited in functionality, and although mentioned in passing in the D-style Variadic Functions documentation, it isn't listed as a Phobos module. With regard to functionality, std.stdarg contains a single function ("va_arg") which interprets _argptr as a pointer to type T, returns a T and advances _argptr by T.sizeof adjusted to 32-bit alignment (see Issue 4310). This is unsafe, as _argptr may not actually be T* and therefore will be mis-aligned post va_arg. Given that D provides type safe Variadic Functions via the _arguments TypeInfo[], a better solution whould be to use the correct TypeInfo.tsize when advancing _argptr. Further more, there are use cases (std.boxer/std.variant, etc) which work with void*/TypeInfo directly and must currently maintain correct stack alignment manually. As a solution to these issues, I'm proposing the VariadicArguments range listed below. Note that switching the assert in get to enforce should allow all methods to be trusted or safe. /** Iterates a set of D-style variadic function arguments in a safe manner. * Example: * -------- void foo(...) { auto va_args = VariadicArguments(_arguments,_argptr) ; assert(va_args.length == 6); assert(va_args.get!uint == 1); va_args.popFront; assert(va_args.get!int == 2); va_args.popFront; assert(va_args.get!long == 3); va_args.popFront; assert(va_args.get!float == 4); va_args.popFront; assert(va_args.get!double == 5); va_args.popFront; assert(va_args.get!real == 6); va_args.popFront; } foo(1u,2,3L,4f,5.0,6.0L); * -------- */ struct VariadicArguments { private TypeInfo[] args; private void* ptr; this(TypeInfo[] arguments, void* argptr) { args = arguments; ptr = argptr; } /// Returns: true if there are no more arguments bool empty() const nothrow { return args.empty; } /// Returns: a copy of this. VariadicArguments save() nothrow { return this; } const(VariadicArguments) save() const nothrow { return this; } ///ditto /// Advances to the next argument void popFront() { ptr = ptr + ((args.front.tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)); args.popFront; } /// Returns: a tuple of an untyped pointer to the current argument and it's TypeInfo. Tuple!(void*,TypeInfo) front() { return tuple(ptr,args.front); } /// Returns: the number of arguments size_t length() const nothrow { return args.length; } /// Returns: the current argument interpreted as type T T get(T)() nothrow { assert(typeid(T).toString() == args.front.toString(), "VariadicArguments.get: mis-matching types: "~typeid(T).toString~" vs. "~args.front.toString); return *cast(T*)ptr; } } unittest { void foo(...) { auto va_args = VariadicArguments(_arguments,_argptr) ; assert(va_args.length == 6); assert(va_args.get!uint == 1); va_args.popFront; assert(va_args.get!int == 2); va_args.popFront; assert(va_args.get!long == 3); va_args.popFront; assert(va_args.get!float == 4); va_args.popFront; assert(va_args.get!double == 5); va_args.popFront; assert(va_args.get!real == 6); va_args.popFront; } foo(1u,2,3L,4f,5.0,6.0L); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 26 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5494 Brad Roberts <braddr puremagic.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |braddr puremagic.com --- I think this one can be closed with the next release. druntime's vararg support has been updated to support the x86-64 c abi. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 07 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5494 Well, I think Issue 4310 can be closed, so long as std.stdarg gets depreciated in favor of core.stdarg. There is an API mismatch between the 32-bit and 64-bit core.stdarg, which should be fixed (I'd suggest making core.stdarg simply forward to core.stdc.stdarg, which is correct). Also, I think the idea of a range which wraps _arguments, _argptr and provides a simple and safe way to use variadic arguments would be a useful enhancement to dRuntime. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 07 2011