将限定符添加到指向类型是一种隐式转换,而删除限定符需要显式转换。
的原型的bsearch()
编写方式允许以下两种用法而无需显式强制转换:
int needle = 0xdeadbeef;
int foo[42] = { ... };
int *p = bsearch(&needle, foo, 42, sizeof *foo, cmpi);
const int bar[42] = { ... };
const int *q = bsearch(&needle, bar, 42, sizeof *bar, cmpi);
然而,这意味着可以使用bsearch()
- 以及许多其他 libc 函数 - 在没有警告的情况下删除 const-qualification,例如,如果我们编写了
int *q = bsearch(&needle, bar, 42, sizeof *bar, cmpi);
这是完全合法的:未定义的行为只有在我们实际习惯于修改时才会q
发生bar
。
您还应该记住,对指针参数进行 const 限定只会影响哪些参数在没有强制转换的情况下被接受,但不能保证函数不会修改指向的对象。这只是几乎所有现有代码都遵循的约定,但它不是由语言语义强制执行的。
特别是,编译器不能使用此信息在调用代码中进行优化 - 编译器需要查看函数体,因为如果对象本身不是,则从指针中删除 const 限定并修改指向的对象是合法的t 宣布const
。
过去,我假设对指针参数进行额外的限制限定会强制执行不变性,但仔细重新阅读第 6.7.3.1 节让我相信情况并非如此:对指向的对象施加的约束限制限定的指针只有在指针实际用于访问对象时才生效,但调用代码不能仅从原型做出这种假设......