View mode: basic / threaded / horizontal-split · Log in · Help
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
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
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
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';
Top | Discussion index | About this forum | D home