Thread overview | ||||||
---|---|---|---|---|---|---|
|
August 31, 2012 va_list ARM changes | ||||
---|---|---|---|---|
| ||||
I tested the changes as in revision 59f52c69d79b10c81913e837ecb14dad0c5fe264: I wasn't sure what exactly should be tested, this is the test case I used: http://dpaste.dzfl.pl/c362e632 (not sure why it doesn't compile on dpaste, it works with my local dmd and gdc installation) This was the output: -------- foo Test test 42 -0.481002 42 Hello [10, 0, 0, 0, 200, 69, 246, 190, 0, 1] -------- * Formatting the struct works, the vprintf example works as well. * Test2 fails, the float is not read correctly. Could be related to the hardfloat API? (it does work on x86 dmd, can't text x86 gdc right now). More complicated examples with floats usually lead to segmentation faults. * Test3 does not work either. Seems passing static arrays doesn't work. However, this also doesn't work on x86/dmd so maybe I'm doing something wrong? It seems this is alignment related though: I guess va_arg always expects the arguments to be aligned, but ubyte[10] isn't aligned? If the value passed to the function is a ulong, but read as a ubyte[8] everything is fine (on arm and on x86/dmd), if the value is passed as a ubyte[8] and read as a ubyte[8] it doesn't work: -------- ubyte[8] c = cast(ubyte[8])[0,1,2,3,4,5,6,7]; test3("", 42, "Hello", *(cast(ulong*)&c)); //WORKS -------- |
August 31, 2012 Re: va_list ARM changes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | On 31 August 2012 11:28, Johannes Pfau <nospam@example.com> wrote: > I tested the changes as in revision 59f52c69d79b10c81913e837ecb14dad0c5fe264: > > I wasn't sure what exactly should be tested, this is the test case I > used: http://dpaste.dzfl.pl/c362e632 > (not sure why it doesn't compile on dpaste, it works with my local dmd > and gdc installation) > This was the output: > -------- > foo > Test test 42 > -0.481002 > 42 Hello [10, 0, 0, 0, 200, 69, 246, 190, 0, 1] > -------- > Part of where you are going wrong is that 'va_arg (va_list, TypeInfo, void*)' should only be used when the static type is indeterminable. This is typically only for structs and classes. All basic types should go through the normal va_arg template functions - these actually get expanded intrinsically by the gcc backend and *do* the right thing, even for your float example. Now that is not to say that you can't use 'va_arg (va_list, TypeInfo, void*)' for basic types, but you do need to be aware of type promotions when it comes to va_args. :-) Eg: void main() { test2("", cast(float)3.45f, "TestTest"); // float is promoted to double when passed as a vararg. } void test2(string input, ...) { double f; string s; va_list list; va_start(list, input); va_arg(list, typeid(typeof(f)), &f); va_arg(list, typeid(typeof(s)), &s); va_end(list); writefln("%s %s", f, s); } And you'll see that test2() in your paste works. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; |
August 31, 2012 Re: va_list ARM changes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | Am Fri, 31 Aug 2012 12:49:37 +0100 schrieb Iain Buclaw <ibuclaw@ubuntu.com>: > Part of where you are going wrong is that 'va_arg (va_list, TypeInfo, void*)' should only be used when the static type is indeterminable. This is typically only for structs and classes. All basic types should go through the normal va_arg template functions - these actually get expanded intrinsically by the gcc backend and *do* the right thing, even for your float example. OK, then everything is working as expected. > > Now that is not to say that you can't use 'va_arg (va_list, TypeInfo, void*)' for basic types, but you do need to be aware of type promotions when it comes to va_args. :-) > > Eg: > > void main() > { > test2("", cast(float)3.45f, "TestTest"); // float is promoted to > double when passed as a vararg. > } > > void test2(string input, ...) > { > double f; > string s; > va_list list; > va_start(list, input); > va_arg(list, typeid(typeof(f)), &f); > va_arg(list, typeid(typeof(s)), &s); > va_end(list); > writefln("%s %s", f, s); > } > > > And you'll see that test2() in your paste works. > Still doesn't work for me, but if basic types should not be used with that va_arg overload and as the templated version works fine anyway it doesn't matter. |
August 31, 2012 Re: va_list ARM changes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | On 31 August 2012 13:05, Johannes Pfau <nospam@example.com> wrote: > Am Fri, 31 Aug 2012 12:49:37 +0100 > schrieb Iain Buclaw <ibuclaw@ubuntu.com>: > >> Part of where you are going wrong is that 'va_arg (va_list, TypeInfo, void*)' should only be used when the static type is indeterminable. This is typically only for structs and classes. All basic types should go through the normal va_arg template functions - these actually get expanded intrinsically by the gcc backend and *do* the right thing, even for your float example. > > OK, then everything is working as expected. >> >> Now that is not to say that you can't use 'va_arg (va_list, TypeInfo, void*)' for basic types, but you do need to be aware of type promotions when it comes to va_args. :-) >> >> Eg: >> >> void main() >> { >> test2("", cast(float)3.45f, "TestTest"); // float is promoted to >> double when passed as a vararg. >> } >> >> void test2(string input, ...) >> { >> double f; >> string s; >> va_list list; >> va_start(list, input); >> va_arg(list, typeid(typeof(f)), &f); >> va_arg(list, typeid(typeof(s)), &s); >> va_end(list); >> writefln("%s %s", f, s); >> } >> >> >> And you'll see that test2() in your paste works. >> > Still doesn't work for me, but if basic types should not be used with that va_arg overload and as the templated version works fine anyway it doesn't matter. > Boo! I should have really brought my ARM device with me so I could test this... unfortunately I left it at home 300 miles away. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; |
Copyright © 1999-2021 by the D Language Foundation