为什么将“指针到非常量指针”转换为不合法?指向“指向 const 指针的指针”
将非常量指针转换为常量指针是合法的。
那么为什么将指向非 const 的指针转换为指向 const 的指针是不合法的呢?
例如,为什么下面的代码是非法的:
char *s1 = 0;
const char *s2 = s1; // OK...
char *a[MAX]; // aka char **
const char **ps = a; // error!
It is legal to convert a pointer-to-non-const to a pointer-to-const.
Then why isn't it legal to convert a pointer to pointer to non-const to a pointer to pointer to const?
E.g., why is the following code illegal:
char *s1 = 0;
const char *s2 = s1; // OK...
char *a[MAX]; // aka char **
const char **ps = a; // error!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从标准来看:
From the standard:
忽略您的代码并回答您问题的原理,请参阅 comp.lang.c FAQ 中的此条目:
为什么我不能将 char ** 传递给需要 const char ** 的函数?
由于您的问题被标记为 C++ 而不是 C,它甚至解释了要使用什么
const
限定符:Ignoring your code and answering the principle of your question, see this entry from the comp.lang.c FAQ:
Why can't I pass a char ** to a function which expects a const char **?
And as your question is tagged C++ and not C, it even explains what
const
qualifiers to use instead:由于没有人发布解决方案,这里:
(http://www.parashift.com/c++-faq-lite/const- Correctness.html#faq-18.17 了解原因)
Just since nobody has posted the solution, here:
(http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17 for why)
C++11 标准草案 在
4.4
节的注释中解释了这一点,其中写道:一个有趣的相关问题是 给定 int **p1 和 const int **p2 是 p1 == p2 格式良好?。
请注意 C++ FAQ 对此也有解释,但我喜欢标准的解释更好。
注释中的一致文本如下:
The C++11 draft standard explains this in a note in section
4.4
which says:An interesting related question is Given int **p1 and const int **p2 is p1 == p2 well formed?.
Note the C++ FAQ also has an explanation for this but I like the explanation from the standard better.
The conforming text that goes with the note is as follows:
这里有两个规则需要注意:
T*
和U*
之间没有隐式转换。T*
隐式转换为T const *
。 (“指向 T 的指针”可以转换为“指向 const T 的指针”)。在 C++ 中,如果T
也是指针,那么该规则也可以应用于它(链接)。例如:
char**
表示:指向 char 的指针。const char**
的意思是:指向 const char 的指针。由于指向 char 的指针和指向 const char 的指针是不同的类型,仅在常量方面不同,因此不允许进行强制转换。正确的转换类型应该是指向 char 的 const 指针。
因此,为了保持 const 正确,您必须从最右边的星号开始添加 const 关键字。
因此,
char**
可以转换为char * const *
,也可以转换为const char * const *
。此链接仅适用于 C++。在 C 中,这种链接不起作用,因此在该语言中,您无法正确转换多于一层的指针 const。
There are two rules here to note:
T*
andU*
if T and U are different types.T*
toT const *
implicitly. ("pointer to T" can be cast to "pointer to const T"). In C++ ifT
is also pointer then this rule can be applied to it as well (chaining).So for example:
char**
means: pointer to pointer to char.And
const char**
means: pointer to pointer to const char.Since pointer to char and pointer to const char are different types that don't differ only in const-ness, so the cast is not allowed. The correct type to cast to should be const pointer to char.
So to remain const correct, you must add the const keyword starting from the rightmost asterisk.
So
char**
can be cast tochar * const *
and can be cast toconst char * const *
too.This chaining is C++ only. In C this chaining doesn't work, so in that language you cannot cast more than one levels of pointers const correctly.