I'm writing a vapi file for a non-gobject API. One of the object types is reference-counted, but rather than a function, unref is a macro of the form:
#define Tcl_DecrRefCount(objPtr) do { ... } while(0) As an unref_function, Vala wants to put this in an expression like so: #define _Tcl_DecrRefCount0(var) \ ((var == NULL) ? NULL : (var = (Tcl_DecrRefCount (var), NULL))) The problem here is that the `do` construct is not an exact substitute for a function call. It's a statement rather than an expression, so you can't have it in a comma sequence like that. GCC fails with the following error: error: expected expression before 'do' #define _Tcl_DecrRefCount0(var) ((var == NULL) ? NULL : (var = (Tcl_DecrRefCount (var), NULL))) ^ note: in expansion of macro '_Tcl_DecrRefCount0' _Tcl_DecrRefCount0 (obj); ^~~~~~~~~~~~~~~~~~ This bug would only arise with an API where an object's unref_function is a macro, and that macro uses the `do` idiom. I don't know how common that is, but I've at least seen it in both the Python and Tcl APIs. I suspect that the practical solution is to wrap the macro in a function and call it a day. But (since this is for a hobby project) I took a look through the compiler internals instead. This is what I found: The macro is generated in Vala.CCodeBaseModule, by destroy_value, which returns a CCodeExpression. Everywhere destroy_value is called, the expression is wrapped in a CCodeExpressionStatement, the result of which is discarded. I can't figure out any reason why destroy_value needs to be an expression, rather than a sequence of statements. If I were to convert this function to output statements instead, the `do` macro would be legit. I kind of want to give it a shot - does anybody have any objections or suggestions? - dpk _______________________________________________ vala-list mailing list vala-list@gnome.org https://mail.gnome.org/mailman/listinfo/vala-list