On Thu, Jan 08, 2026 at 04:32:34PM +0100, Michal Prívozník via Devel wrote:
> On 1/8/26 14:39, [email protected] wrote:
> > Hi there and a happy new year! I have a question regarding your comments.
> > Basic C types (pointers and const qualifiers) are read from right to left,
> > with the exception that the the first two components can be exchanged if
> > one is `const`. Hence:
> >
> > char *: mutable pointer to mutable chars
> > const char *: mutable pointer to const chars (read-only view into any
> > string)
> > char const*: same as ^
> > const char * const: const pointer to const chars (read-only view into a
> > fixed string)
> > const char * const: same as ^
> >
> > So I'm reading `g_autofree const char *leases_str = NULL;` as:
> >
> > `leases_str` offers read-only view into any string, and frees what is
> > behind this pointer once it goes out of scope.
> >
> > So how can `g_autofree const char *leases_str = NULL;` be a problem? I'd
> > only see `g_autofree const char * const leases_str = NULL;` to be
> > problematic, which we clearly do not have here.
> >
> > My C may be a bit..rusty and I'm not familiar in libvirt coding
> > conventions, so I might be missing something?
> >
>
> It's not your C skills. But having 'char *' often means the function is
> also the owner of allocated memory, where as 'const char *' means the
> function is given an immutable reference. It doesn't map 1:1 into Rust,
> sorry. In Rust you can clearly distinguish mutability and data ownership
> on a type level (that's why rustc can reason about your code). It's not
> that clear in C.
An easier way to rationalize this is to consider that g_autofree
essentially gets turned back into the manual free() pattern by
the compiler
ie you write
g_autofree const char *lease_str = NULL;
...
and it gets effectively turned back into
const char *lease_str = NULL;
...
g_free(leases_str);
and if you tried to compile that you'd get
a.c:11:8: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier
from pointer target type [-Wdiscarded-qualifiers]
11 | free(f)
| ^
In file included from a.c:2:
/usr/include/stdlib.h:687:25: note: expected ‘void *’ but argument is of type
‘const char *’
687 | extern void free (void *__ptr) __THROW;
| ~~~~~~^~~~~
a.c:11:10: error: expected ‘;’ before ‘__attribute__’
11 | free(f)
| ^
it is unfortunate the the compiler can't warn about use of 'const' with
attribute(cleanup), but we should still imagine that it should, hence
my suggestion to add a syntax-check to fill the gap.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|