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.

Here's the code we're talking about:

int main(...)
{
    g_autofree char *leases_str = NULL;
    ...
    if (!(leases_str = virJSONValueToString(leases_array_new, true))) {
       ...
    }

    if (virFileRewriteStr(custom_lease_file, 0644, leases_str) < 0)
        goto cleanup;
    ...
}

Here, virJSONValueToString() allocates a new string and returns it to
the caller, making it also the owner of it. The only way not change the
string is, well, not touch it. Okay, perhaps the following might work too:

  g_autofree char *leases_str = virJSONValueToString(..);
  const char *leases_str_const = leases_str;

  // use leases_str_const only

but you see how convoluted that is. Back in the day, when I was at
university I also heard an explanation that compiler is free to place
'const' data into a RO memory (which we don't really have, unless you're
on an embed system).

Michal

Reply via email to