常量,正确性和不可改变的分配对象 [英] Const-correctness and immutable allocated objects
问题描述
在最近的讨论(见注释<一个href=\"http://stackoverflow.com/questions/3965279/opaque-c-structs-how-should-they-be-declared/3965308#3965308\">this回答),R ..建议不要为了指针别名 - 常量
类型,你将不能够很容易地释放了被引用的对象标准的C程序(记住:免费()
需要一个非 - 常量
指针参数和C99 6.3.2.3只允许来自非限定转换到合格线)。
During a recent discussion (see comments to this answer), R.. recommended to never create aliases for pointer-to-const
types as you won't be able to deallocate the referenced objects easily in a conforming C program (remember: free()
takes a non-const
pointer argument and C99 6.3.2.3 only allows conversions from non-qualified to qualified).
C语言显然不承担任何分配的对象的所有者是否存在等,即某人在某处具有存储非 - 常量
指向对象的指针,而这个人是负责释放。
The C language obviously assumes the existance of an owner for any allocated object, ie someone somewhere has to store a non-const
pointer to the object, and this someone is responsible for deallocation.
现在,考虑一个图书馆分配和初始化它们是从用户空间code非modifyable对象,所以函数调用总是返回常量
-qualified指针。
Now, consider a library allocating and initializing objects which are non-modifyable from user-space code, so function calls always return const
-qualified pointers.
显然,该库是对象的所有者,并应保留非 - 常量
指针,这是有点傻的用户已经提供了一个完全有效的,但常量
指针在每个库调用拷贝。
Clearly, the library is the owner of the object and should retain a non-const
pointer, which is somewhat silly as the user already supplies a perfectly valid, but const
copy of the pointer on each library call.
要释放这样一个对象,库中有放弃常量
预选赛;据我所知,以下
To deallocate such an object, the library has to discard the const
qualifier; as far as I can tell, the following
void dealloc_foo(const struct foo *foo)
{
free((void *)foo);
}
有效期℃;它只会是无效的,如果在富
参数是另外限制
-qualified。
is valid C; it would only be invalid if the foo
parameter were additionally restrict
-qualified.
不过,虚掷常量
似乎有点劈十岁上下。
However, casting away const
seems somewhat hack-ish.
有另一种方式除了掉落常量
从库函数所有的返回值,这将失去有关对象的可变性的信息吗?
Is there another way aside from dropping the const
from all return values of library functions, which would lose any information about object mutability?
推荐答案
我不读同样的事情在6.3.2.3。该段是关于隐式发生,并且不需要强制转换的转换。因此,从一个指针到的隐式转换 - 常量
对象可能被禁止,但这种只字未提显式转换。
I don't read the same thing in 6.3.2.3. That paragraph is about conversions that happen implicitly and that don't need a casts. So an implicit conversion from a pointer-to-const
object may be not permitted, but this says nothing about explicit casts.
强制类型转换在6.5.4处理,我没有看到任何会限制你的任何投指针到 - 常量
即本身不常量
资格与(无效*)
。在相反它说:
Casts are handled in 6.5.4, and I don't see anything that would constrain you from a cast of any pointer-to-const
that is by itself not const
qualified with (void*)
. In the contrary it says
转换涉及三分球,
不到哪里被允许的其他
约束
6.5.16.1,应以显式类型转换的方式来指定。
Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast.
所以我看了那里,如果你做的事情明确,他们是允许的。
So I read there that if you do things explicitly, they are permitted.
所以,我认为以下是完全有效的
So I think the following is completely valid
char const *p = malloc(1);
free((void*)p);
6.5.4什么会forbits是以下 char * const的P =的malloc(1);
免费的((无效*)p); / *投前pression是const修饰* /
作为一个方面说明,你的思绪第二行,返回一个指针到库 - 常量
合格的对象,则是被放置在责任来电者,使得没有多少意义,我。无论
What 6.5.4 forbits would be the following
char *const p = malloc(1);
free((void*)p); /* expression of cast is const qualified */
As a side note, for your second line of thoughts, a library that returns a pointer-to-const
qualified object that then is to be placed in the responsibility of the caller, makes not much sense to me. Either
- 库返回一个指针
内部对象,那么就应该
限定它的指针到 -常量
有一些薄弱
保护调用者不
改变它,或者 - 库返回一个新鲜
分配的对象,在瀑布
来电者的责任。然后,它
应该不会太在乎的是否
来电者的变化,所以它可能会返回
一个指针到不合格的对象。如果呼叫者
然后希望确保该
内容是不小心
覆盖或东西,他可能
它分配给常量
指针,为
他使用。
- the library returns a pointer to an
internal object, then it should
qualify it pointer-to-
const
to have some weak protection that the caller doesn't change it, or - the library returns a freshly
allocated object that falls in the
responsibility of the caller. Then it
shouldn't care much of whether the
caller changes it, so it may return
a pointer-to-unqualified object. If the caller
then wants to ensure that the
contents is not accidentally
overwritten or something he might
assign it to a
const
pointer, for his use.
这篇关于常量,正确性和不可改变的分配对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!