mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-13 15:56:23 +01:00
Add g_autofree
The g_autoptr() being associated with the type name works out really well for things like GHashTable. However, it's a bit more awkward to associate with "gchar". Also because one can't use "char". Similarly, there are a lot of other "bare primitive array" types that one might reasonably use. This patch does not remove the autoptr for "gchar", even though I think it's rather awkward and strange. Also while we're here, add a test case for the cleanup bits. https://bugzilla.gnome.org/show_bug.cgi?id=744747
This commit is contained in:
parent
2844f239f6
commit
d0105f1c08
34
glib/docs.c
34
glib/docs.c
@ -2422,6 +2422,40 @@
|
||||
* Since: 2.44
|
||||
*/
|
||||
|
||||
/**
|
||||
* g_autofree:
|
||||
*
|
||||
* Macro to add an attribute to pointer variable to ensure automatic
|
||||
* cleanup using g_free().
|
||||
*
|
||||
* This macro differs from g_autoptr() in that it is an attribute supplied
|
||||
* before the type name, rather than wrapping the type definition. Instead
|
||||
* of using a type-specific lookup, this macro always calls g_free() directly.
|
||||
*
|
||||
* This means it's useful for any type that is returned from
|
||||
* g_malloc().
|
||||
*
|
||||
* Otherwise, this macro has similar constraints as g_autoptr() - only
|
||||
* supported on GCC and clang, the variable must be initialized, etc.
|
||||
*
|
||||
* |[
|
||||
* 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;
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* Since: 2.44
|
||||
*/
|
||||
|
||||
/**
|
||||
* G_DEFINE_AUTOPTR_CLEANUP_FUNC:
|
||||
* @TypeName: a type name to define a g_autoptr() cleanup function for
|
||||
|
@ -21,6 +21,14 @@
|
||||
#error "Only <glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
g_autoptr_cleanup_generic_gfree (void *p)
|
||||
{
|
||||
void **pp = (void**)p;
|
||||
if (*pp)
|
||||
g_free (*pp);
|
||||
}
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAsyncQueue, g_async_queue_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBookmarkFile, g_bookmark_file_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBytes, g_bytes_unref)
|
||||
|
@ -402,6 +402,7 @@
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
#define g_autoptr(TypeName) _GLIB_CLEANUP(_GLIB_AUTOPTR_FUNC_NAME(TypeName)) _GLIB_AUTOPTR_TYPENAME(TypeName)
|
||||
#define g_auto(TypeName) _GLIB_CLEANUP(_GLIB_AUTO_FUNC_NAME(TypeName)) TypeName
|
||||
#define g_autofree _GLIB_CLEANUP(g_autoptr_cleanup_generic_gfree)
|
||||
|
||||
#else /* not GNU C */
|
||||
/* this (dummy) macro is private */
|
||||
|
@ -200,6 +200,12 @@ check-am: gtester-xmllint-check
|
||||
private_LDFLAGS = @G_THREAD_LIBS@
|
||||
endif
|
||||
|
||||
if HAVE_GCC
|
||||
test_programs += \
|
||||
autoptr \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
if HAVE_EVENTFD
|
||||
|
37
glib/tests/autoptr.c
Normal file
37
glib/tests/autoptr.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <glib.h>
|
||||
|
||||
static void
|
||||
test_autofree (void)
|
||||
{
|
||||
g_autofree char *p = NULL;
|
||||
g_autofree char *p2 = NULL;
|
||||
g_autofree char *alwaysnull = NULL;
|
||||
|
||||
p = g_malloc (10);
|
||||
p2 = g_malloc (42);
|
||||
|
||||
if (TRUE)
|
||||
{
|
||||
g_autofree guint8 *buf = g_malloc (128);
|
||||
g_autofree char *alwaysnull_again = NULL;
|
||||
|
||||
buf[0] = 1;
|
||||
}
|
||||
|
||||
if (TRUE)
|
||||
{
|
||||
g_autofree guint8 *buf2 = g_malloc (256);
|
||||
|
||||
buf2[255] = 42;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/autoptr/autofree", test_autofree);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user