Return int reference in vala

327 views Asked by At

I have a class that has fields and I want call a method of this class and get the reference to one of the fields (not the value!!). Something like this:

class Test : Object{
    uint8 x;
    uint8 y;
    uint8 z;

    uint8 method(){
        if (x == 1){
            return y;
        }else if (x == 2){
            return z;
        }
    }

    public static void main(string[] args){
        uint8 i = method(); // get reference to y or z
        i++;  //this must update y or z
    }
}

In C would be:

int& method()
{
    if (x == 1){
        return y;
    }else if (x == 2){
        return z;
    }
}

How can I achieve this in vala?

Edit: I'm trying use pointers, I have the following

public class Test : Object {

    private Struct1 stru;

    struct Struct1{
        uint8 _a;


        public uint8 a{
            get{ return _a; }
            set{ _a = value; }
        }


        public Struct1(Struct1? copy = null){
            if (copy != null){
                this._a = copy.a;
            }else{
                this._a = 0;
            }
        }

        public uint8* get_aa(){
            return (uint8*)a;

        }
    }

    public void get_pointer(){
        uint8* dst = stru.get_aa();
    }

    public static int main (string[] args){


        Test t = new Test();

        return 0;
    }

}

but when I compile I get

/home/angelluis/Documentos/vala/test.vala.c: In function ‘test_struct1_get_aa’:
/home/angelluis/Documentos/vala/test.vala.c:130:11: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  result = (guint8*) _tmp1_;
           ^
Compilation succeeded - 2 warning(s)

Why? I am returning an uint8* type and I attempt to store it in an uint8* pointer.

1

There are 1 answers

1
Jens Mühlenhoff On BEST ANSWER

C doesn't have references (C++ does). Keep in mind that Vala compiles to C as an intermediate language.

I think that there are only two ways to do this in Vala:

  1. Use a box type to encapsulate your uint8 values and return a reference to that box type.

  2. Use a pointer. (Which opens the obvious pointer can of worms)

Edit: Answer to your updated example code problem:

You must be very careful with casting something to some pointer type. In this case the C compiler caught your spurious cast and emited a warning.

uint8 _a;

// This property will get and set the *value* of _a
public uint8 a{
    get{ return _a; }
    set{ _a = value; }
}

public uint8* get_aa(){
    // Here you are casting a *value* of type uint8 to a pointer
    // Which doesn't make any sense, hence the compiler warning
    return (uint8*)a;
}

Note that you can't get a pointer or a reference to a property, because properties have no memory location on their own.

You can however get a pointer to the field _a in this case:

public uint8* get_aa(){
    return &_a;
}

If you insist to go through the property, you have to make your property operate on the pointer as well:

    uint8 _a;

    public uint8* a{
        get{ return &_a; }
    }

Notice that in this version I have removed the get_aa () method which is now equivalent to the getter for a.

Also since in this code the property is returning a pointer there is no need for a setter, you can just dereference the pointer to set the value.