Cannot use GValue with variadic arguments
Trying to get a GValue out of a varargs list does not compile.
Example:
void problem(int x, ...) {
var l = va_list();
Value val = l.arg();
print(val.get_string());
}
int main(string[] args) {
Value val = Value(typeof(string));
val.set_string("Hello, world!");
problem(0, val);
return 0;
}
Valac will compile this code, but the resulting C does not compile.
Here is the resulting C code:
/* main.c generated by valac 0.45.2.2-8f86b, the Vala compiler
* generated from main.vala, do not modify */
#include <glib.h>
#include <stdarg.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
void problem (gint x,
...);
gint _vala_main (gchar** args,
gint args_length1);
void
problem (gint x,
...)
{
va_list l = {0};
GValue val = {0};
GValue _tmp0_ = {0};
const gchar* _tmp1_;
#line 2 "main.vala"
va_start (l, x);
#line 3 "main.vala"
if (G_IS_VALUE (&va_arg (l, GValue))) {
#line 3 "main.vala"
g_value_init (&_tmp0_, G_VALUE_TYPE (&va_arg (l, GValue)));
#line 3 "main.vala"
g_value_copy (&va_arg (l, GValue), &_tmp0_);
#line 32 "main.c"
} else {
#line 3 "main.vala"
_tmp0_ = va_arg (l, GValue);
#line 36 "main.c"
}
#line 3 "main.vala"
val = _tmp0_;
#line 4 "main.vala"
_tmp1_ = g_value_get_string (&val);
#line 4 "main.vala"
g_print ("%s", _tmp1_);
#line 1 "main.vala"
G_IS_VALUE (&val) ? (g_value_unset (&val), NULL) : NULL;
#line 1 "main.vala"
va_end (l);
#line 48 "main.c"
}
gint
_vala_main (gchar** args,
gint args_length1)
{
gint result = 0;
GValue val = {0};
GValue _tmp0_ = {0};
GValue _tmp1_;
#line 8 "main.vala"
g_value_init (&_tmp0_, G_TYPE_STRING);
#line 8 "main.vala"
val = _tmp0_;
#line 9 "main.vala"
g_value_set_string (&val, "Hello, world!");
#line 11 "main.vala"
_tmp1_ = val;
#line 11 "main.vala"
problem (0, &_tmp1_, NULL);
#line 12 "main.vala"
result = 0;
#line 12 "main.vala"
G_IS_VALUE (&val) ? (g_value_unset (&val), NULL) : NULL;
#line 12 "main.vala"
return result;
#line 75 "main.c"
}
int
main (int argc,
char ** argv)
{
#line 7 "main.vala"
return _vala_main (argv, argc);
#line 84 "main.c"
}
And here is the relevant build output:
In file included from /usr/include/glib-2.0/gobject/gobject.h:24,
from /usr/include/glib-2.0/gobject/gbinding.h:29,
from /usr/include/glib-2.0/glib-object.h:23,
from main.c:6:
main.vala: In function ‘problem’:
main.vala:3:18: error: lvalue required as unary ‘&’ operand
3 | Value val = l.arg();
| ^
/usr/include/glib-2.0/gobject/gtype.h:2288:58: note: in definition of macro ‘_G_TYPE_CHV’
2288 | #define _G_TYPE_CHV(vl) (g_type_check_value ((GValue*) vl))
| ^~
/usr/include/glib-2.0/gobject/gvalue.h:50:29: note: in expansion of macro ‘G_TYPE_CHECK_VALUE’
50 | #define G_IS_VALUE(value) (G_TYPE_CHECK_VALUE (value))
| ^~~~~~~~~~~~~~~~~~
main.vala:3:6: note: in expansion of macro ‘G_IS_VALUE’
3 | Value val = l.arg();
| ^~~~~~~~~~
In file included from /usr/include/glib-2.0/gobject/gobject.h:25,
from /usr/include/glib-2.0/gobject/gbinding.h:29,
from /usr/include/glib-2.0/glib-object.h:23,
from main.c:6:
main.vala:3:40: error: lvalue required as unary ‘&’ operand
3 | Value val = l.arg();
| ^
/usr/include/glib-2.0/gobject/gvalue.h:59:43: note: in definition of macro ‘G_VALUE_TYPE’
59 | #define G_VALUE_TYPE(value) (((GValue*) (value))->g_type)
| ^~~~~
main.vala:3:17: error: lvalue required as unary ‘&’ operand
3 | Value val = l.arg();
| ^
ninja: build stopped: subcommand failed.