[zz] 包含const限定符的参数传递
本文转载自 Wisen’s blog http://wisenyoyo.spaces.live.com/blog/cns!7c30d6a00f8b277d!124.entry
Robbie 个人认为这主要是在于 constness 的兼容性问题。如果说是实际应用场合中不方便的话,可以将 const 限定去除,或者为保险起见,编一个函数作一下强制转换也可。最好不要直接作强制转换以免在修改类型时没有任何警告。用函数的好处是,比如说:
char **pp1;
const char **pp2 = to_const_ppchar(pp1);
const char **to_const_ppchar(char **ppch)
{
return (const char **)ppch;
}
一旦 pp1 的类型改掉了,比如改成 char *pp1 了,那么编译器就会给出个警告。如果直接在代码中强制转换,如:
const char **pp2 = (const char **)pp1;
那一旦 pp1 变成了 char *pp1,没有警告,实际上就引入了一个潜在的漏洞了。
- 左操作数是一个指向有const限定符的char的指针;
- 右操作数是一个指向没有限定符的char的指针;
- char类型与char类型是相容的,左操作数所指向的类型具有右操作数所指向类型的限定符(这里没有),再加上自身的限定符(const)。
注意:反过来就不能进行赋值,如果不信,试试下面的代码:
cp = cpp; /*结果产生编译警告*/
标准第6.3.16.1节有没有说char **实参与const char **形参是相容的?没有。
标准第6.1.2.5节中讲述实例的部分声称:
“const float *类型并不是一个有限定符的类型——它的类型是‘指向一个具有const限定符的float类型的指针’,也就是说const限定符是修饰指针所指向的类型,而不是指针本身”。
类似地,const char **也是一个没有限定符的指针类型,即:(((const char)*)*)p。它的类型是“指向一个有const限定符的char类型变量的指针的指针”,由于char **和const char **都是没有限定符的指针类型,但它们所指向的类型不一样(前者指向char *,后者指向const char *),因此他们是不相容的,因此,类型为char **的实参与类型为const char **的形参是不相容的,违反了标准第6.3.2.2节所规定的约束条件,编译器必然会产生一条诊断信息。
关键字const并不能把变量变成常量!在一个符号前加上const限定符只是表示这个符号不能被赋值。也就是它的值对于这个符号来说是只读的,但他并不能防止通过程序的内部(甚至是外部)的方法来修改这个值。const最有用之处就是用它来限定函数的形参,这样该函数将不会修改实参指针所指向的数据,但其他的函数却可能会修改它:这也许就是C和C++中const最一般的用法。
const和*的组合通常只用于在数组形式的参数中模拟传值调用。它声称“我给你一个指向它的指针,但你不能修改它。”这个约定类似于极为常见的void *的用法,尽管在理论上它可以用于任何情况,但通常被限制于把指针从一种类型转换为另一种类型。