问题
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:
- Linus Torvalds'
kfree()
, unlike C'sfree()
, takes avoid 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.- C++'s delete operators allow deletion of const data.
Arguments against it include:
- Programmers do not expect data to be modified (or deleted) when they pass a pointer-to-const to it.
- Many think that pointer-to-const implies not getting ownership of the data (but not that non-const would imply getting ownership).
- This is the common practice seen in most libraries and existing code.
Please argument well in your responses and possibly refer to authorities. My intention is not to start a poll here.
回答1:
Well, here's some relevant stuff possibly too long to fit into a comment:
Some time ago the practice to free memory via a pointer-to-const was plain forbidden, see this dr. Dobb's article, the "Language Law" ( :)) part.
There has twice been a relevant discussion on http://groups.google.ru/group/comp.lang.c++.moderated: "Delete a const pointer?", "Why can operator delete be called on a const pointer" (both actually deal with the case in question, i.e. pointer to const).
My own point (since you are asking for arguments): possibility of the operation in question in any given context is defined by the (explicitly or implicitly defined in the documentation) contract of a class or a function, not by just the method signature or parameter types.
回答2:
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.)
回答3:
I've never really understood the arguments against deleting (or freeing) a const pointer. More precisely, I somewhat see the rational but it seems to me that they apply equally well to a const member in an object or a const variable in a bloc, and I've never see anybody argue that those should not be destroyed and their memory freed when the containing object is deleted or the execution leaves their containing block.
The two issues of managing the logical mutability of objects (i.e. const or not) and managing their life length (i.e. use an object variable, a smart pointer -- which and one -- or a raw pointer) seems unrelated to me.
In other words, if
{
Foo const x;
...
}
is valid and good style. Why would
{
Foo const* xptr = new Foo;
...
delete xptr;
}
not be good style (using an adequate smart pointer instead of a raw one, but that is another issue).
回答4:
Constness and lifetime are two different things. I see no problem freeing a const object if the owner of that object decides the object has no reason to live (the same way a const
object that's a local will get 'deallocated' when it goes out of scope).
As far as free()
not taking a const
pointer, I think that one could argue either that that might have been an oversight of the standards committee or that that's because it takes the same kind if pointer that malloc()
returns.
来源:https://stackoverflow.com/questions/2288291/is-it-a-good-practice-to-free-memory-via-a-pointer-to-const