Question

I'm trying to free a pointer to a volatile buffer (the pointer is not volatile [I think...])

void try_this(volatile int* vint)
{
    free(vint);
}

gives me:

warning: passing argument 1 of 'free' discards qualifiers from pointer target type

This seems to offer an explanation that would be valid for freeing: int * volatile vint http://lists.freebsd.org/pipermail/freebsd-hackers/2005-January/009652.html

It seems to suggest that because the pointer could be pointing to invalid memory (because it is volatile it could have changed outside the normal flow of the program/thread) and this is why the behavior is discouraged, but... The pointer in this case (as far as I am aware) is not volatile, its the data thats pointed to thats volatile, surely free shouldn't care if this changes?

Can anyone offer a better explanation? (or reason why im totally wrong!)

Was it helpful?

Solution 2

The warning isn't specific to free and doesn't have anything to do with what free does, it's merely because there's no volatile qualifier in free's prototype. If you don't want the warning, just use a cast:

free((void*)vint);

OTHER TIPS

You assumption is incorrect. Since volatile is written on the left side of the *, it means that you have a pointer to volatile data. This data, like any dynamically-allocated data, could change as much as it pleases between malloc and free. The free function does not care.

If you for some reason had int* volatile vint, then you would have a volatile pointer to data and your concerns would be valid, because then there would perhaps be no guarantees that the pointer itself has remained the same between malloc and free. But there is no reason to write such code, so it isn't a concern.

The actual reason you are getting the warning is simply because free expects a void* and you are passing a volatile int*. C can do implicit casts between void* and int*, but if you add a type qualifier such as volatile or const, then a decent compiler will give a warning instead of silently accept the cast.

You can solve the problem by either typing free((int*)vint) or free((void*)vint), they are equally correct.


As a rule of thumb: it is fine to turn a regular pointer into one with const or volatile, but not the other way around:

int* a;
const int* b=a;    // fine
int* c=b;          // possible bug and/or bad practice
volatile int* d=a; // fine
int* e=d;          // possible bug and/or bad practice
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top