There are many questions discussing the details of C and C++ dealing with pointer-to-const deletion, namely that free()
does not accept them and that delete
and delete[]
do and that constness doesn't prevent object destruction.
What I am interested on is whether you think it is a good practice to do so, not what the languages (C and C++) allow.
Arguments for pointer-to-const deletion include:
kfree()
, unlike C's free()
, takes a void const*
argument because he thinks that freeing the memory does not affect what is pointed to.free()
was designed before the introduction of the const keyword.Arguments against it include:
Please argument well in your responses and possibly refer to authorities. My intention is not to start a poll here.
The pointer will point to no object afterwards if you only set it to null, but the memory of the object it pointed to previously won't be freed. So in effect you will leak memory by doing that.
We can create a constant pointer in C, which means that the value of the pointer variable wouldn't change. We can create a pointer to a constant in C, which means that the pointer would point to a constant variable (created using const).
A const pointer to a const value can not have its address changed, nor can the value it is pointing to be changed through the pointer. It can only be dereferenced to get the value it is pointing at.
In the pointers to constant, the data pointed by the pointer is constant and cannot be changed. Although, the pointer itself can change and points somewhere else (as the pointer itself is a variable).
It is a good practice to use the proper strategy to end the lifetime of an object. For dynamic objects this means delete what you new, free what you malloc, and so forth. Whether that object is const or not has no affect on whether its lifetime should end.
Being constant or volatile are properties that exist within an object's lifetime, and that ends with a delete-expression or a call to free. Regardless of your own views on the matter or how things work in other languages, this is how C++'s object model works. A simple example to show this is how the language translates delete-expressions into operator delete calls:
#include <new>
void* operator new(std::size_t size);
void operator delete(void* p);
int main() {
delete new int(); // int* to void*, since this is also an allowed
// implicit conversion, it may not be clear what is happening
// however, these are clearly not implicit conversions:
delete new int const(); // int const * to void*
delete new int volatile(); // int volatile* to void*
delete new int const volatile(); // int const volatile* to void*
}
Another example, but perhaps less clear, is why you cannot overload ctors on const:
struct S {
S() const; // not allowed
};
An object is only const after it is created (aka its lifetime begins; happens when the ctor returns normally) and before it is destroyed (aka its lifetime ends; happens as the dtor is entered). Before or after that lifetime you may have a pointer of type T const*
(for example), but it does not point to an object and dereferencing it is UB.
The same line of reasoning applies to C, except you have to consider that C has roughly 40 years of history and has succeeded in maintaining a large amount of consistency for much of that time.
(I believe this question is subjective and argumentative and would vote to close it that way, except I apparently helped spark the discussion; so answering as CW.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With