GNOME Bugzilla – Bug 774738
Calling g_error_free on a null pointer should not print an error message
Last modified: 2016-11-28 19:22:20 UTC
Created attachment 340335 [details] [review] [PATCH] gerror: Define g_error_free(NULL) to be a no-op Currently, if you call g_error_free on a null pointer, you will see: GLib-CRITICAL **: g_error_free: assertion 'error != NULL' failed This behavior is really counterintuitive because g_free and g_slice_free both return silently if passed a null pointer, the same as the standard C free function. g_clear_error also returns silently. Calling gerror's free function on a null pointer should likewise not be considered an error at all, much less a critical one. The attached patch resolves the problem.
If you look at the rest of the API in GLib you'll quickly realize that only g_free() and g_slice_free() are NULL-safe — mostly because they are wrappers around free(), which *must* be NULL-safe. The rest of the destruction functions are generally not NULL safe to catch improper use. GError, and g_error_free(), are not the exception. If you want to check and NULL-ify a pointer, use g_clear_error() or g_clear_pointer().
(In reply to Alex Henrie from comment #0) > Currently, if you call g_error_free on a null pointer, you will see: > > GLib-CRITICAL **: g_error_free: assertion 'error != NULL' failed > > This behavior is really counterintuitive because g_free and g_slice_free > both return silently if passed a null pointer I believe the justification for this is: some_type_free() (or some_type_unref() for refcounted types), for some object or data structure named SomeType, expects to get a pointer to a SomeType as a parameter. In particular, it is a programming error (undefined behaviour) to call those functions with a pointer to memory that does not in fact contain a SomeType. GLib can't reliably detect that, but it tries to give a critical warning where possible (for example if you g_object_unref() something that is not actually a GObject, you'll often get a critical warning). A NULL pointer of type SomeType * does not point to a SomeType either - the closest you can say is that it represents the absence of a SomeType. So it is not considered valid to pass NULL to those functions either. g_free, g_slice_free and Standard C free are different because they are one level of abstraction further down: conceptually, they operate on undifferentiated regions of memory, not on objects. The designers of Standard C free chose to consider "free a pointer to no memory" to be a valid operation, and g_free, g_slice_free follow that.