Why instance_size is 0 for fundamental GType types?

There are a bunch of fundamental types being registered in GLib’s GType subsystem (GLib’s source file gvaluetypes.c follows):

    /* --- type initialization --- */
    void
    _g_value_types_init (void)
    {
      GTypeInfo info = {
        0,				/* class_size */
        NULL,			/* base_init */
        NULL,			/* base_destroy */
        NULL,			/* class_init */
        NULL,			/* class_destroy */
        NULL,			/* class_data */
        0,				/* instance_size */
        0,				/* n_preallocs */
        NULL,			/* instance_init */
        NULL,			/* value_table */
      };
      const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
      GType type G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;
      
      /* G_TYPE_CHAR / G_TYPE_UCHAR
       */
      {
        static const GTypeValueTable value_table = {
          value_init_long0,		/* value_init */
          NULL,			/* value_free */
          value_copy_long0,		/* value_copy */
          NULL,			/* value_peek_pointer */
          "i",			/* collect_format */
          value_collect_int,	/* collect_value */
          "p",			/* lcopy_format */
          value_lcopy_char,		/* lcopy_value */
        };
        info.value_table = &value_table;
        type = g_type_register_fundamental (G_TYPE_CHAR, g_intern_static_string ("gchar"), &info, &finfo, 0);
        g_assert (type == G_TYPE_CHAR);
        type = g_type_register_fundamental (G_TYPE_UCHAR, g_intern_static_string ("guchar"), &info, &finfo, 0);
        g_assert (type == G_TYPE_UCHAR);
      }
      …
      …
      …

I wonder why instance_size of info struct isn’t being used? Don’t fundamental types have/use any “instance size”? I’m planning on using this subsystem to register a few types,
including fundamental ones, and I wonder if I should specify,
e.g.: 8 for instance_size for a gint64–equivalent type?

In general, what’s wrong with specifying a true, real size of a basic type? It shouldn’t do any harm? If yes, then why GLib’s doesn’t use this feature ?

Not all fundamental types have an instance: only the ones that have the G_TYPE_FLAG_INSTANTIATABLE flag set do.

A char type does not have an instance: this is not Java.

No, you don’t.

Also: don’t register a new fundamental type for an int64_t type. Derive your type from G_TYPE_INT64 instead:

static GType
your_type_get_type_once (void)
{
  const GTypeInfo type_info = {
    .class_size = 0,
    .base_init = NULL,
    .base_finalize = NULL,
    .class_init = NULL,
    .class_finalize = NULL,
    .class_data = NULL,
    .instance_size = 0,
    .n_preallocs = 0,
    .instance_init = NULL,
    .value_table = NULL,
  };

  return g_type_register_static (G_TYPE_INT64,
                                 g_intern_static_string ("YourType"),
                                 &type_info, 0);
}

GType
your_type_get_type (void)
{
  static gsize static_gtype;

  if (g_once_init_enter (&static_gtype))
    {
      GType real_type = your_type_get_type_once ();
      g_once_init_leave (&static_gtype, real_type);
    }

  return gtype;
}

I then wonder why register such basic types like char, boolean or int? What’s the use case?

Because you need a GType in order to be able to store them into a GValue, and then marshal the values for properties and signals.

Those values are copied, not allocated.

So basically, by registering a plain GType one (has to) provide raw-byte access functions (e.g.: value_copy_int64, value_collect_int64, value_lcopy_int64) in GTypeValueTable so that GValue inner workings can support such arranged bytes? That’s interesting, because that’s a tangible effect – if one registers the type with GType, then he’ll get GValue support. I wouldn’t see anything such useful comming from registering a. say. int-like type in a type system. After all, isn’t the idea of type systems mostly hooked onto runtime type information? E.g., be able to check if an object is of given type. However,I wonder if GValue can have some use case outside GObject and its properties, etc. What can you use GValues for in a regular code?

Another set of non-instantiable fundamental types would be fractions, int/int64/double ranges, bitmasks, etc. in GStreamer.

They’re (together with ints etc) used not just for properties/signals there, but also for GstCaps / GstStructure. That’s how GStreamer e.g. represents media formats, and based on this there’s various infrastructure to serialize/deserialize these things and to provide set operations on them (say, one component accepts 2-4 audio channels and another 2-6, what’s the possible range both support?).

But as you say, code dealing with these types need to know about them. The only thing that can be done otherwise is the generic GValue API to e.g. check the type. But that’s not different at all to instantiable fundamental types (say GtkExpression).

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.