>From: Jason Merrill <[email protected]> >On 08/13/2014 08:36 PM, Jason Merrill wrote: >>>> From: John McCall <[email protected]> >>>> This is clearly the right way for any vendor who wants to accept non-POD >>>> variadic arguments to do it: no solution involving memcpy can be >>>> correct for all types >> >> Yep. The only question is whether it's better, for code that is in a >> gray area of the standard, to stick with the broken historical practice >> or do something more correct.
>Since there is incompatible existing practice and the code is only >conditionally-supported anyway, perhaps sticking with existing practice >is the right answer even though it breaks the object model. >On the other hand, perhaps since the code is only >conditionally-supported, compatibility with existing practice isn't as >important. Jason I wrote a better test case to test both caller and callee sides and also looked up the warning and found a test case from an important customer. So someone is using it. :-) >From: John McCall <[email protected]> >> On the other hand, perhaps since the code is only conditionally-supported, >> compatibility with existing practice isn't as important. >I'm not sure we really do have existing practice on this. Dennis, I >apologize if Im misunderstanding you, but it sounds like you consider >this to be undefined behavior Well the message indicates it. And it won't work in all cases. I.e. if you put the address inside itself, that won't match. But I did look up the warnings and found a test case from an important customer. (I'm not sure if there were other customers that had an actual but different use of this?) But looking real close at it, this won't be a problem, since used in template metaprogramming: char tIsP(bool, tfoo); char* tIsP(bool, ...); template<class T> struct tIsPtr { enum { tRet= (sizeof(tIsP(true,*(T*)0))== 1) }; }; >(which is an allowed interpretation in fact, >that was the explicit wording prior to C++11) and hence do not feel like >you've made a promise to support users relying on aCCs current >behavior. Well for this customer we would have to. :-) I.e. At least not give an error, since not really called. >In that case, we can adopt Jasons proposal, and aCC can >freely choose whether to continue its current practice indefinitely >(since how they implement undefined behavior is their own business) >or move to Jason's proposed rule (since doing so wouldn't break >compatibility with well-defined programs). John. Sure. Here is my test case and the results: #include <stdio.h> #include <stdarg.h> struct foo { foo() : i(88) { printf("%p: foo ctor\n", this); } ~foo() { printf("%p: foo dtor\n", this); } foo(const foo &that) : i(that.i + 1) { printf("%p: foo cctor(%p)\n", this, &that); } int i; }; int bar(int anchor, ...) { va_list ap; va_start(ap, anchor); foo b = va_arg(ap, foo); printf("bar's b.i is: %d\n", b.i); return anchor; } int main() { foo f; f.i = 99; printf("try this: %.16llx\n", f); return bar(0, f); } "class_vararg.c", line 20: warning #3291-D: a non-POD class type cannot be fetched by va_arg foo b = va_arg(ap, foo); ^ "class_vararg.c", line 28: warning #3290-D: Passing a non-POD object to a function with variable arguments has undefined behavior. Object will be copied onto the stack instead of using a constructor. printf("try this: %.16llx\n", f); ^ "class_vararg.c", line 28: warning #2181-D: argument is incompatible with corresponding format string conversion printf("try this: %.16llx\n", f); ^ "class_vararg.c", line 29: warning #3290-D: Passing a non-POD object to a function with variable arguments has undefined behavior. Object will be copied onto the stack instead of using a constructor. return bar(0, f); ^ $ a.out 7fffe7c0: foo ctor try this: 0000006300000000 7fffe764: foo cctor(7fffe760) bar's b.i is: 100 7fffe764: foo dtor 7fffe7c0: foo dtor The ctors and dtors balance.
_______________________________________________ cxx-abi-dev mailing list [email protected] http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev
