Add support for the cleanup attribute in GCC/Clang

The new json_auto_t macro allows easy declaration of json_t types that
automatically decrement at the end of their scope.
This commit is contained in:
Nathaniel McCallum 2016-08-30 16:12:22 -04:00
parent ab1ba69027
commit 63b9fd0552
3 changed files with 44 additions and 0 deletions

View File

@ -253,6 +253,24 @@ other. Moreover, trying to encode the values with any of the encoding
functions will fail. The encoder detects circular references and functions will fail. The encoder detects circular references and
returns an error status. returns an error status.
Scope Dereferencing
-------------------
It is possible to use the ``json_auto_t`` type to automatically
dereference a value at the end of a scope. For example::
void function(void) {
json_auto_t *value = NULL;
value = json_string("foo");
/* json_decref(value) is automatically called. */
}
This feature is only available on GCC and Clang. So if your project
has a portability requirement for other compilers, you should avoid
this feature.
Additionally, as always, care should be taken when passing values to
functions that steal references.
True, False and Null True, False and Null
==================== ====================

View File

@ -112,6 +112,19 @@ void json_decref(json_t *json)
json_delete(json); json_delete(json);
} }
#if defined(__GNUC__) || defined(__clang__)
static JSON_INLINE
void json_decrefp(json_t **json)
{
if(json) {
json_decref(*json);
*json = NULL;
}
}
#define json_auto_t json_t __attribute__((cleanup(json_decrefp)))
#endif
/* error reporting */ /* error reporting */

View File

@ -224,4 +224,17 @@ static void run_tests()
json_incref(value); json_incref(value);
if(value->refcount != (size_t)-1) if(value->refcount != (size_t)-1)
fail("refcounting null works incorrectly"); fail("refcounting null works incorrectly");
#ifdef json_auto_t
value = json_string("foo");
{
json_auto_t *test = json_incref(value);
/* Use test so GCC doesn't complain it is unused. */
if(!json_is_string(test))
fail("value type check failed");
}
if(value->refcount != 1)
fail("automatic decrement failed");
json_decref(value);
#endif
} }