自动清理

自动清理

GLib提供了一组宏,用于封装GCC扩展,以在变量超出作用域时自动清理这些变量。

这些宏仅能与GCCGCC兼容的C编译器一起使用。

变量声明

g_auto(TypeName)

用于声明带有自动清理的变量的辅助函数。

当变量超出作用域时,将以符合其类型的方式清理该变量。该变量的TypeName必须支持此功能。

清理类型的方式必须已通过宏 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC()G_DEFINE_AUTO_CLEANUP_FREE_FUNC() 之一定义。

此功能仅在GCC和clang上受支持。在其他的编译器上此宏没有被定义,不应在旨在能够适用于这些编译器的程序中使用。

此宏旨在与栈分配的结构和非指针类型一起使用。对于(更常用)指针版本,请参阅 g_autoptr()

此宏可用于在退出函数时避免执行显式的局部变量清理。它通常大大简化了错误条件处理,消除了使用各种技巧(如“goto out”或重复清理代码)的需求。这对于非错误情况也有帮助。

考虑以下示例:

GVariant *
my_func(void)
{
  g_auto(GQueue) queue = G_QUEUE_INIT;
  g_auto(GVariantBuilder) builder;
  g_auto(GStrv) strv;

  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
  strv = g_strsplit("a:b:c", ":", -1);

  // ...

  if (error_condition)
    return NULL;

  // ...

  return g_variant_builder_end (&builder);
}

您必须以某种方式初始化变量——无论是使用初始化器还是确保在它超出作用域之前,总会无条件地调用它上的_init函数。

自:2.44

g_autoptr(TypeName)

声明带有自动清理的指针变量的辅助函数。

当变量超出作用域时,将以符合其类型的方式清理该变量。该变量的TypeName必须支持此功能。清理类型的方式必须使用宏 G_DEFINE_AUTOPTR_CLEANUP_FUNC() 定义。

此功能仅在GCC和clang上受支持。在其他的编译器上此宏没有被定义,不应在旨在能够适用于这些编译器的程序中使用。

这通常用于声明指向具有清理函数的类型的指针。变量的类型是指向TypeName的指针。您不得添加自己的*

此宏可用于在退出函数时避免执行显式的局部变量清理。它通常大大简化了错误条件处理,消除了使用各种技巧(如“goto out”或重复清理代码)的需求。这对于非错误情况也有帮助。

考虑以下示例:

gboolean
check_exists(GVariant *dict)
{
  g_autoptr(GVariant) dirname, basename = NULL;
  g_autofree gchar *path = NULL;

  dirname = g_variant_lookup_value (dict, "dirname", G_VARIANT_TYPE_STRING);
  if (dirname == NULL)
    return FALSE;

  basename = g_variant_lookup_value (dict, "basename", G_VARIANT_TYPE_STRING);
  if (basename == NULL)
    return FALSE;

  path = g_build_filename (g_variant_get_string (dirname, NULL),
                           g_variant_get_string (basename, NULL),
                           NULL);

  return g_access (path, R_OK) == 0;
}

您必须以某种方式初始化变量——无论是使用初始化器还是确保在它超出作用域之前,总会无条件地给它赋值。

另请参阅:g_auto()g_autofree()g_steal_pointer()

自:2.44

g_autofree

宏,用于向指针变量添加属性,以确保使用g_free()进行自动清理。

g_autoptr()不同,此宏是在类型名称之前提供的属性,而不是包装在类型定义周围。它直接调用g_free(),而不是使用特定类型的查找。

这意味着对于从g_malloc()返回的任何类型都很有用。

否则,此宏具有与g_autoptr()类似的约束:仅受GCC和clang支持,变量必须初始化等。

gboolean
operate_on_malloc_buf (void)
{
  g_autofree guint8* membuf = NULL;

  membuf = g_malloc (8192);

  // Some computation on membuf

  // membuf will be automatically freed here
  return TRUE;
}

自:2.44

g_autolist(TypeName)

用于声明具有自动深度清理的列表变量的辅助函数。

当变量超出作用域时,列表会按照指定的类型以适当的方式进行深层释放。必须支持这种行为。

此功能仅在GCC和clang上受支持。在其他的编译器上此宏没有被定义,不应在旨在能够适用于这些编译器的程序中使用。

这旨在用于声明带有清理函数的类型列表。变量的类型是 GList *。您不得添加自己的 *

此宏可用于在退出函数时避免执行显式的局部变量清理。它通常大大简化了错误条件处理,消除了使用各种技巧(如“goto out”或重复清理代码)的需求。这对于非错误情况也有帮助。

另请参阅:g_autoslist()g_autoptr()g_steal_pointer()

自:2.56

g_autoslist(TypeName)

帮助声明带有自动深度清理的单链表变量。

当变量超出作用域时,列表会按照指定的类型以适当的方式进行深层释放。必须支持这种行为。

此功能仅在GCC和clang上受支持。在其他的编译器上此宏没有被定义,不应在旨在能够适用于这些编译器的程序中使用。

这旨在用于声明带有清理函数的类型列表。变量的类型是 GSList *。您不得添加自己的 *

此宏可用于在退出函数时避免执行显式的局部变量清理。它通常大大简化了错误条件处理,消除了使用各种技巧(如“goto out”或重复清理代码)的需求。这对于非错误情况也有帮助。

另请参阅:g_autolist()g_autoptr()g_steal_pointer()

自:2.56

g_autoqueue(TypeName)

帮助声明带有自动深度清理的双端队列变量。

当变量超出作用域时,队列会按照指定的类型以适当的方式进行深层释放。必须支持这种行为。

此功能仅在GCC和clang上受支持。在其他的编译器上此宏没有被定义,不应在旨在能够适用于这些编译器的程序中使用。

这旨在用于声明带有清理函数的类型队列。变量的类型是 GQueue *。您不得添加自己的 *

此宏可用于在退出函数时避免执行显式的局部变量清理。它通常大大简化了错误条件处理,消除了使用各种技巧(如“goto out”或重复清理代码)的需求。这对于非错误情况也有帮助。

另请参阅:g_autolist()g_autoptr()g_steal_pointer()

自:2.62

类型定义

G_DEFINE_AUTOPTR_CLEANUP_FUNC(TypeName, func)

定义指针类型的适当清理函数。

如果要清理的变量包含 NULL,则不会调用该函数。

这通常是给定类型的 _free()_unref() 函数。

使用此定义,可以与给定的 TypeName 一起使用 g_autoptr()

G_DEFINE_AUTOPTR_CLEANUP_FUNC(GObject, g_object_unref)

此宏应无条件使用;在某些编译器上,清理不受支持时,它是一个无操作。

自:2.44

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(TypeName, func)

为类型定义适当的清理函数。

这通常是给定类型的 _clear() 函数。

使用此定义,可以与给定的 TypeName 一起使用 g_auto()

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GQueue, g_queue_clear)

此宏应无条件使用;在某些编译器上,清理不受支持时,它是一个无操作。

自:2.44

G_DEFINE_AUTO_CLEANUP_FREE_FUNC(TypeName, func, none_value)

为类型定义适当的清理函数。

使用此定义,可以与给定的 TypeName 一起使用 g_auto()

该函数很少使用。它与基于指针的 typedef 和非指针类型一起使用,其中变量的值代表必须释放的资源。两个例子是 GStrv 和文件描述符。

none_value 指定所涉及类型的“none”值。它可能是 NULL-1。如果发现变量中含有此值,则不会调用释放函数。

G_DEFINE_AUTO_CLEANUP_FREE_FUNC(GStrv, g_strfreev, NULL)

此宏应无条件使用;在某些编译器上,清理不受支持时,它是一个无操作。

自:2.44