Search code examples
pointersparameter-passingvala

vala: parameter directions - automated null value check of value-type out parameter


PROBLEM:

I am actually having problems to utilize a seemingly nice feature advertised on the Vala/Tutorial site regarding the declaration of output paramaters.

Here the quote from: https://live.gnome.org/Vala/Tutorial#Parameter_Directions

Here is an example of how to implement method_1():

void method_1(int a, out int b, ref int c) {
    b = a + c;
    c = 3; }

When setting the value to the out argument "b", Vala will ensure that "b" is not null. So you can safely pass null as the second argument of method_1() if you are not interested by this value.

Taking a look at the generated C code it seems obvious that in contradiction to the claims made above instead of making a check prior to assignment the possible NULL pointer is happily dereferenced instead.

void method_1 (gint a, gint* b, gint* c) {
    *b = a + (*c);
    *c = 3;
}

The code that I expected would have taken this form instead:

void method_1 (gint a, gint* b, gint* c) {
    if (b != NULL)
      *b = a + (*c);
    *c = 3;
}

The only workaround I found so far is to throw the whole out parameter declaration away and directly go with a pointer instead.

void method_1 (gint a, int* b, ref int c) {
    if (b != null)
      *b = a + c;
    c = 3;
}

For esthetic resons I pretty much liked the idea mentioned in the quotation made above, so I want to ask the following

QUESTIONS:

  • Did I misinterpret the description in the quotation made above and and value-type parameters declared out can't autmatically be checked for null pointers?

  • Or is this probably a bug in the vala compiler, that's fixed in later version? valac --version returns Vala 0.8.1 so this is the version I am using.

  • Is there perhaps any other chance to perform a check of an out declared value-type parameter by hand by any language element I am still missing?


Solution

  • Vala 0.8.1 is your problem. Vala 0.16 produced

    void method_1 (gint a, gint* b, gint* c) {
      gint _vala_b = 0;
      gint _tmp0_;
      gint _tmp1_;
      _tmp0_ = a;
      _tmp1_ = *c;
      _vala_b = _tmp0_ + _tmp1_;
      *c = 3;
      if (b) {
        *b = _vala_b;
      }
    }