Currently I'm trying/invesigating to make a library based on the glib/gobject libraries. So I'm trying to make a mathematical vector in GObject style. Vectors can be added together so what I'm trying to implement is in pseudo code is: v1 = [1, 2, 3, 4]
, v2 = [1, 2, 3, 4]
and v_add_result = v1 + v2
. As you can see, a new vector should be allocated for the result and for this operation v1 and v2 do not change and hence, I would like to have those const qualified.
from my-vector.h:
#define MY_TYPE_VECTOR (my_vector_get_type())
G_DECLARE_DERIVABLE_TYPE(MyVector, my_vector, MY, VECTOR, GObject)
struct _MyVectorClass
{
GObjectClass parent_class;
MyVector* (*add) (const MyVector* self, const MyVector* other);
void (*add_is)(MyVector* self, const MyVector* other);
MyVector* (*sub) (const MyVector* self, const MyVector* other);
void (*sub_is)(MyVector* self, const MyVector* other);
};
MyVector* my_vector_new();
MyVector* my_vector_new_vals(double v1, double v2, double v3, double v4);
// This is the function which in theory could be implemented with const MyVectors
MyVector* my_vector_add(const MyVector* self, const MyVector* rhs);
Then to implement the addition I have a public addition function, which checks its inputs for being valid MyVector instances. However, if I try to check whether the the instances are valid MyVector instances, I receive a warning about the macro's that should according the gobject system check whether a pointer actually point to a valid MyVector instance.
and a fragment from the my-vector.c:
MyVector*
my_vector_add(const MyVector* self, const MyVector* other)
{
g_return_if_fail(MY_IS_VECTOR(self));
g_return_if_fail(MY_IS_VECTOR(other));
const MyVectorClass* klass = MY_VECTOR_GET_CLASS(self);
g_return_if_fail(klass->add != NULL);
return klass->add(self, other);
}
The compiler warning I get is:
In file included from /usr/lib/x86_64-linux-gnu/glib-2.0/include/glibconfig.h:9:0,
from /usr/include/glib-2.0/glib/gtypes.h:32,
from /usr/include/glib-2.0/glib/galloca.h:32,
from /usr/include/glib-2.0/glib.h:30,
from /usr/include/glib-2.0/gobject/gbinding.h:28,
from /usr/include/glib-2.0/glib-object.h:23,
from /home/maarten/programming/c/gobject/my-vector.h:6,
from /home/maarten/programming/c/gobject/my-vector.c:2:
/home/maarten/programming/c/gobject/my-vector.c: In function ‘my_vector_add’:
/home/maarten/programming/c/gobject/my-vector.c:214:35: warning: passing argument 1 of ‘MY_IS_VECTOR’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
g_return_if_fail(MY_IS_VECTOR(self));
this results in a warning because the MY_IS_VECTOR() macro results in code that does not respect const qualified GObjects or in this case GObject derived instances such as MyVector.
Does the gobject system ignore const correctness, or do they have another way to achieve this?
Also if I look at other libraries based on gobject for example gtk(+) I see signatures like const gchar* gtk_label_get_text (GtkLabel *label);
The function returns a const gchar*
, so the label doesn't change, it too could be using a const GtkLabel*
.
Does the gobject system ignore const correctness
Correct, const
-correctness is ignored when dealing with GObjects and other reference-counted things. It’s a design decision which was taken a long time ago in GObject’s development, and I don’t know the exact reasons for it. It’s likely because trying to be const
-correct would have ended up requiring a lot of casts so that ‘const’ objects could have their reference count temporarily increased while being queried, before being decreased again, for example.