[英]typedef pointer const weirdness
请考虑以下代码:
typedef struct Person* PersonRef;
struct Person {
int age;
};
const PersonRef person = NULL;
void changePerson(PersonRef newPerson) {
person = newPerson;
}
出于某种原因,编译器抱怨只读值不可分配。 但是const
关键字不应该使指针成为 const。 有任何想法吗?
注意
typedef int* intptr;
const intptr x;
不等同于:
const int* x;
intptr
是指向 int 的指针。 const intptr
是指向int
常量指针,而不是指向常量int
指针。
所以,在 typedef 指针之后,我不能再让它成为内容的常量了?
有一些丑陋的方式,比如 gcc 的typeof 宏:
typedef int* intptr;
intptr dummy;
const typeof(*dummy) *x;
但是,如您所见,如果您知道intptr
背后的类型,那将毫无意义。
const PersonRef person = NULL;
是
struct Person*const person= NULL;
所以你正在构造指针而不是对象。
虽然上面的答案已经解决了问题,但我确实想念为什么......
所以也许作为一个经验法则:
const
总是指它的前身标记。这个规则真的可以帮助你声明一个指向 const 指针的指针或同样简洁的东西。
无论如何,考虑到这一点,应该清楚为什么
struct Person *const person = NULL;
声明一个指向可变结构的const 指针。
想想看,您的 typedef 将struct Person
与指针标记*
“分组” 。 所以,对于写作
const PersonRef person = NULL;
您的编译器会看到类似的内容(伪代码):
const [struct Person *]person = NULL;
由于const
的左边没有任何东西,它会将标记释放到它的右边struct Person *
constant。
好吧,我想,这就是为什么我不喜欢通过 typedef 隐藏指针,而我确实喜欢 typedef 这样的原因。 写作呢
typedef struct Person { ... } Person;
const Person *person; /*< const person */
Person *const pointer; /*< const pointer to mutable person */
编译器和人类应该很清楚你在做什么。
永远不要在 typedef 后面隐藏指针,这真的是非常糟糕的做法,只会产生错误。
一个臭名昭著的错误是,声明为 const 的 typedef:ed 指针类型将被视为“指向非常量数据的常量指针”,而不是“指向常量数据的非常量指针”,这是人们直觉所期望的. 这就是您的程序中发生的情况。
解决方案:
typedef struct
{
int age;
} Person;
const Person* person = NULL; // non-constant pointer to constant Person
作为 Piotr(已接受)答案的补充,可以避免 GCC 特定的typeof
:
static_assert(std::is_same<const int *, std::add_const_t<std::remove_pointer_t<intptr>> *>::value, "not same via type_traits");
static_assert(std::is_same<const int *, std::remove_reference_t<decltype(std::as_const(*intptr()))>*>::value, "not same via decltype");
通过将foo_t<T>
更改为上面的foo<T>::type
和/或使用 boost 的版本,甚至可以在 C++98 中做到这一点,尽管它只是自 C++11 以来才漂亮。
或者,使用两个不同的 typedef,这也适用于普通指针以外的情况。 例如,考虑每个容器的iterator
和const_iterator
类型定义。
你得到和错误
error: assignment of read-only variable ‘person’
在声明中
person = newPerson;
因为你已经将 person 声明为 const 所以它的值是只读的.... const 值不能改变
如果你要改变那个可变的那么你为什么要保持它不变?
删除 const 关键字,您的代码可以正常工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.