D.gnu - va_list ARM changes
- Johannes Pfau (30/30) Aug 31 2012 I tested the changes as in revision
- Iain Buclaw (31/44) Aug 31 2012 Part of where you are going wrong is that 'va_arg (va_list, TypeInfo,
- Johannes Pfau (6/40) Aug 31 2012 OK, then everything is working as expected.
- Iain Buclaw (7/47) Aug 31 2012 Boo!
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 --------
Aug 31 2012
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';
Aug 31 2012
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.
Aug 31 2012
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>: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';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.
Aug 31 2012