On 15.07.2014 15:27, Martin Kletzander wrote:
On Tue, Jul 15, 2014 at 02:38:36PM +0200, Michal Privoznik wrote:
> Up to now it's possible to do something like this:
>
> const char *ptr;
>
> ptr = strdup("my example string");
>
> VIR_FREE(ptr);
>
> The problem is, const char * pointers should not be modified (and
> freeing them is kind of modification). We should avoid this. A little
> trick is used: assigning a const pointer into 'void *' triggers
> compiler warning about discarding 'const' qualifier from pointer. So
> the virFree() function gains new dummy argument, that is not touched
> anyhow, just fulfills the const correctness check duty.
>
> Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
> ---
> src/util/viralloc.c | 6 ++++--
> src/util/viralloc.h | 20 ++++++++++++++++----
> src/xenapi/xenapi_utils.c | 2 +-
> 3 files changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/src/util/viralloc.c b/src/util/viralloc.c
> index be9f0fe..0134e67 100644
> --- a/src/util/viralloc.c
> +++ b/src/util/viralloc.c
[...]
> @@ -569,13 +569,15 @@ int virAllocVar(void *ptrptr,
>
> /**
> * virFree:
> + * @ptr: dummy pointer to check const correctness
> * @ptrptr: pointer to pointer for address of memory to be freed
> *
> * Release the chunk of memory in the pointer pointed to by
> * the 'ptrptr' variable. After release, 'ptrptr' will be
> * updated to point to NULL.
> */
> -void virFree(void *ptrptr)
> +void virFree(void *ptr ATTRIBUTE_UNUSED,
> + void *ptrptr)
What if you don't add another argument, but just change the void
*ptrptr to void **ptrptr. Compiler shouldn't be mad about not knowing
the size resulting of de-referencing ptrptr, you get the check you
want and keep the macro without side-effects.
That won't work. Consider:
char *tmp;
VIR_FREE(tmp);
which in turn is equal to:
virFree(&tmp);
so the &tmp is type of 'char **' while virFree() would expect 'void
**'
which confuses compiler.
Michal