繁体   English   中英

从char * *变量分配给char * const *变量-为什么允许它?

[英]Assigning to a char * const * variable from a char * * variable - why is it allowed?

我对C ++(Visual Studio 2012编译器)的以下行为感到惊讶。

char * * PointerToPointerToChar = NULL;
char * const * PointerToConstPointerToChar = NULL;
char const * * PointerToPointerToConstChar = NULL;

PointerToPointerToConstChar = PointerToPointerToChar; // Assignment 1: Gives compiler error as I would expect
PointerToConstPointerToChar = PointerToPointerToChar; // Assignment 2: NO COMPILER ERROR ???

PointerToPointerToChar = PointerToPointerToConstChar; // Assignment 3: Gives compiler error as I would expect
PointerToPointerToChar = PointerToConstPointerToChar; // Assignment 4: Gives compiler error as I would expect

我了解C ++中的const关键字,尤其是它的位置如何影响const(左侧的实体)。

似乎编译器试图在任一间接级别 (分配3和4)保护RHS变量的用户免受const剥离别名的影响。 但是LHS仅在一个间接级别(分配1)而不在另一个间接级别(分配2)受到保护,免受const剥离别名的侵害。 换句话说,假设编译器阻止了以下操作

PointerToPointerToConstChar = PointerToPointerToChar; // Assignment 1: Gives compiler error as I would expect
PointerToPointerToChar[0][0] = 'A'; // The user of the LHS variable was effectively lied to about the constness of the *characters* - second level of indirection

那么为什么编译器也无法阻止以下操作

PointerToConstPointerToChar = PointerToPointerToChar; // Assignment 2: NO COMPILER ERROR ???
PointerToPointerToChar[0] = NULL; // The user of the LHS variable was effectively lied to about the constness of the *pointers* - first level of indirection

这是正确的C ++吗?如果是,则依据是什么? 似乎不一致。 谢谢!

type const*并不意味着该值不会改变,这意味着您无法使用该指针进行更改。


因为如果可以这样做,则可以将任何const char*分配给*PointerToPointerToConstCharPointerToPointerToChar依靠它为普通char* 如果允许的话:

PointerToPointerToConstChar = PointerToPointerToChar; // assume PointerToPointerToChar is pointing to a valid memory block
const char str[] = "Hello world!";
*PointerToPointerToConstChar = str;
(*PointerToPointerToChar)[0] = 'X'; // Oops, we just modified a const array

char**分配给char* const*类似于将char*分配给const char* 这是很合理的。

char array[] = "foo";
char* ptr1 = array;            // Can change array through ptr1
char const* ptr2 = ptr1;       // Can't change array through ptr2

使用char**char* const*使可以更改和不能更改的内容更加复杂。

char** ptrptr1 = &ptr1;

// Can change where ptr1 points to through ptrptr1
*ptrptr1 = <some other char*>; // OK

// Can change the value of what ptr1 points to through ptrptr1.
(*ptrptr1)[0] = 'x';           // OK

char* const* ptrptr2 = ptr1;

// Can't change where ptr1 points to through ptrptr2
*ptrptr2 = <some other char*>; // Not OK

// Can change the value of what ptr1 points to through ptrptr2.
// (*ptrptr2) is still of type 'char*'.
(*ptrptr2)[0] = 'x';           // OK

您有一个指向const的指针。 指针不是const ,而是它指向的内容。 您可以为该指针分配一个指向非const的指针。 那也行。 指针不是const,在这种情况下const只是告诉我们,指向的对象不会通过此指针更改。 它不必在其他任何地方都是const。

char* c = someCharPointerSomewhere;
PointerToConstPointerToChar = PointerToPointerToChar;
*PointerToConstPointerToChar = c // const violation
*PointerToPointerToChar = c // this is fine
// now *PointerToConstPointerToChar will be c as well.

那为什么不能分配一个指向const的指针呢? 好吧,指向const的指针与指向non const的指针是不同的类型。 我们上面的隐式转换不适用于这种情况。 您可以使用此指针,使其指向的对象实际上是const 然后,原始指针将允许间接修改const值。

const char c = 'c';
PointerToPointerToConstChar = PointerToPointerToChar;
*PointerToPointerToConstChar = c;
**PointerToPointerToChar = 'a'; // const violation!

当您仅阅读说明但花些时间仔细考虑时,这会有些混乱。 这样在逻辑上确实是一致的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM