www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - TypeInfo

reply Derek Parnell <derek psych.ward> writes:
I ran into something unexpected today when dealing with variadic arguments.
Basically, I get a different arguments passed to my function under
different circumstances.

  Foo A  = new Foo(1,3,5);  // I get 3 args, all ints.

  Foo B += new Foo(1,3,5);  // I get 4 args, the first is 'TypeInfo' 

I don't understand why a 'new' for a simple assignment is different from a
'new' in an opAddAssign.

I found a work around but its a bit of a kludge.

The source code to demonstrate this is a bit long, sorry about that.

<--------------- code ------------------->
import std.stdarg;    
import std.stdio;

class Foo{
    static int baseid;
    int id;
    
    long[] Mem;
    
    this(...)
    {
        baseid++;
        id = baseid;
        for (int i = 0; i < _arguments.length; i++)
        {
            if (_arguments[i] is typeid(int))
            {
                Mem.length = Mem.length + 1;
                Mem[length-1] = cast(long)va_arg!(int)(_argptr);
            }
            else if (_arguments[i] is typeid(long))
            {
                Mem.length = Mem.length + 1;
                Mem[length-1] = va_arg!(long)(_argptr);
            }
            else 
            {
                writefln(
                    "unknown data element '%s'" 
                    " at position %d"  
                    " length %d", 
                    _arguments[i].toString,
                    std.string.toString(i),
                    std.string.toString(_arguments[i].tsize())
                    ); 
                    
                // Skip over the bad data.
                if (_arguments[i].tsize() == 0)
                    _argptr += 8;  // Why is size 0 but I have to add 8?
                else
                    _argptr +=
                    ((_arguments[i].tsize() + 
                      int.sizeof - 1) & ~(int.sizeof - 1));
                }
        };
    }
    
    // Does nothing special, just for the demo.
    Foo opAddAssign(Foo x) 
    {
        if (x.Mem.length > Mem.length)
            Mem.length = x.Mem.length;
        foreach(inout long a; Mem)
            foreach(long b; x.Mem)
                a += b;
                
        return this;                
    } 
    
    // Debug display.
    void ShowMe()
    {
        writef("\nFoo #%d --> ", id);
        foreach(int i,long x; Mem)
        {
            writef("%d", x);
            if (i != Mem.length-1)
                writef(",");
        }
        writef("\n");
    }
}

void main() 
{
    Foo A = new Foo;
    A.ShowMe();
    Foo B = new Foo;
    B.ShowMe();
    
    A = new Foo(cast(char)'a', 4.55, 1,2,3,"AA", B, 9,8,6);
    A.ShowMe();

    B = new Foo(1,2,3);        
    B.ShowMe();
    B += A;
    B.ShowMe();
    
    B = new Foo(1,2,3);        
    B.ShowMe();
    B += new Foo(cast(char)'a', 4.55, 1,2,3,"AA", B, 9,8,6);
    B.ShowMe();
    
}
<---------------------------------------->

-- 
Derek
Melbourne, Australia
22/02/2005 3:11:39 PM
Feb 21 2005
parent "Walter" <newshound digitalmars.com> writes:
That looks like a compiler bug. You should get the TypeInfo argument for
both cases.
Feb 25 2005