繁体   English   中英

typedef 指针 const 怪异

[英]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;

所以你正在构造指针而不是对象。

虽然上面的答案已经解决了问题,但我确实想念为什么......

所以也许作为一个经验法则:

  1. const总是指它的前身标记。
  2. 如果没有这样的,它是“consting”,它是后继令牌。

这个规则真的可以帮助你声明一个指向 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,这也适用于普通指针以外的情况。 例如,考虑每个容器的iteratorconst_iterator类型定义。

你得到和错误

error: assignment of read-only variable ‘person’

在声明中

person = newPerson;

因为你已经将 person 声明为 const 所以它的值是只读的.... const 值不能改变

如果你要改变那个可变的那么你为什么要保持它不变?

删除 const 关键字,您的代码可以正常工作

暂无
暂无

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

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