【问题标题】:const correctness in GObjectsGObjects 中的 const 正确性
【发布时间】:2020-09-28 19:53:39
【问题描述】:

目前我正在尝试/研究基于 glib/gobject 库创建一个库。所以我试图用 GObject 风格制作一个数学向量。向量可以加在一起,所以我试图用伪代码实现的是:v1 = [1, 2, 3, 4]v2 = [1, 2, 3, 4]v_add_result = v1 + v2。如您所见,应为结果分配一个新向量,并且此操作 v1 和 v2 不会更改,因此,我希望这些 const 合格。

来自 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);

然后为了实现加法,我有一个公共加法函数,它检查它的输入是否是有效的 MyVector 实例。但是,如果我尝试检查这些实例是否是有效的 MyVector 实例,我会收到有关宏的警告,该警告应根据 gobject 系统检查指针是否实际指向有效的 MyVector 实例。

以及来自 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);
}

我得到的编译器警告是:

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));

这会导致警告,因为 MY_IS_VECTOR() 宏会导致代码不遵守 const 限定的 GObject 或在这种情况下 GObject 派生实例,例如 MyVector。

gobject 系统是否忽略了 const 的正确性,或者他们有其他方法来实现这一点?

另外,如果我查看基于 gobject 的其他库,例如 gtk(+),我会看到像 const gchar* gtk_label_get_text (GtkLabel *label); 这样的签名函数返回 const gchar*,因此标签不会改变,它也可能使用 @987654329 @。

【问题讨论】:

  • 像 GTK 这样的 GObject 样式代码通常尊重字符串的 constness,但很少对对象这样做。 AFAICT,它可能可以,但实际上它不是这样结束的,所以它周围的机器不能很好地支持它。您可以自己定义宏,而不是使用 GLib 宏来为您完成。不过,由于明显的其他原因,这并不是很好。
  • @underscore_d 我有很多东西要学。我将签名更改为MyVector* my_vector_add(MyVector* v1, MyVector* v2),下一个警告出现了,因为 g_return_if_fail 做了类似return; 的事情,并且我的函数返回了一个指针。所以可能它应该通过 MyVector** 作为函数参数返回。
  • 不,你可以g_return_val_if_fail(NULL)代替。

标签: c gobject


【解决方案1】:

gobject 系统是否忽略 const 正确性

正确,const-正确性在处理 GObject 和其他引用计数的事物时被忽略。这是很久以前在 GObject 的开发中做出的设计决定,我不知道它的确切原因。这可能是因为尝试成为const-正确最终会需要大量强制转换,以便“const”对象可以在查询时暂时增加其引用计数,然后再减少,例如。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    相关资源
    最近更新 更多