据我所知,使用const
关键字的主要原因之一是作为文档的一种形式。它保证对象不会在给定的上下文中被修改。特别是,只要不违反我的规则,就声明指针函数参数const
的目标。我的问题与这些规则之一有关。
如果没有在函数中修改目标,也没有它可以访问的任何对象,则我声明指针参数const
的目标。如果仅修改了可以通过指针间接访问的对象,我是否应该将其声明为指向const
对象?这是一个例子:
struct S
{
int* ptr;
};
void f(/*const*/ struct S* s)
{
*s->ptr = 0;
}
s
的目标应该是const
吗?为什么或为什么不呢?
即使语言指向const
对象,也可以修改仅由指针间接引用的对象,但是该语言允许这样做,但是我更愿意做出更强有力的保证。但是,随着我积累了编程经验,我开始怀疑我的约定是否弊大于利。由于我const
的使用至少部分是出于文档目的,因此我也想与其他程序员保持一致,并且我不知道是否已经对此达成共识,并且正在违反。
严格来说,您的f()
函数不会修改构成s
结构的任何字节:ptr
成员不会更改,但是它指向的int
可以位于任何位置,因此可以更改。const
的s
限定词只是阻止我们重新分配ptr
成员使其指向新地址。constness很浅!
这有点违反我们的直觉,这就是为什么在C ++中容器的设计方式是,如果将容器视为const,那么它包含的所有内容(即使这意味着像您的结构)也被视为const。这个深层的[[constness更直观。
很遗憾,我不知道C中的任何解决方案都会自动考虑如果ptr
是const int *
,则将s
成员作为const struct S *
。编辑即使编译器不会阻止您错误地更改*ptr
,参数中const
的用法非常重要。考虑这个例子:
void f(struct S *s); // const omitted, although *s will not be altered
struct S *s1=...;
const struct S *s2=...;
f(s1); // allowed by the compiler
f(s2); // rejected by the compiler!!!!
在非可变结构上使用此功能。 (真可悲!)因此,要直接回答问题,这不仅是一个问题文档。f()
功能无意修改*s
但是,由于省略了const
,我们cannot