typedef指针const古怪

Joh*_*nes 22 c typedef const

请考虑以下代码:

typedef struct Person* PersonRef;
struct Person {
  int age;
};

const PersonRef person = NULL;

void changePerson(PersonRef newPerson) {
  person = newPerson;
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,编译器抱怨只读值不可分配.但是const关键字不应该使指针成为常量.有任何想法吗?

Pio*_*zmo 42

注意

typedef int* intptr;
const intptr x;
Run Code Online (Sandbox Code Playgroud)

是不一样的:

const int* x;
Run Code Online (Sandbox Code Playgroud)

intptr是指向int的指针.const intptr是常量指针int,而不是指向常量的指针int.

所以,在typedef指针之后,我不能再使它成为内容的const?

有一些丑陋的方式,比如gcc的typeof宏:

typedef int* intptr;
intptr dummy;
const typeof(*dummy) *x;
Run Code Online (Sandbox Code Playgroud)

但是,正如你所看到的,如果你知道背后的类型,那就毫无意义了intptr.


Jen*_*edt 7

const PersonRef person = NULL;
Run Code Online (Sandbox Code Playgroud)

struct Person*const person= NULL;
Run Code Online (Sandbox Code Playgroud)

所以你正在构建指针而不是对象.

  • 是的,确切地说,指针`typedef`通常是一个坏主意的原因之一. (3认同)

小智 6

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

所以可能作为一个经验法则:

  1. const总是指它的前身令牌.
  2. 如果没有这样的话,那就是"修改"它的后继令牌.

这个规则可以真正帮助你声明指向const指针或同样整洁的东西.

无论如何,考虑到这一点,它应该明白为什么

struct Person *const person = NULL;
Run Code Online (Sandbox Code Playgroud)

声明一个指向可变结构的const指针.

想想看,你的类型定义"组"struct Person用指针令牌*.所以,写作

const PersonRef person = NULL;
Run Code Online (Sandbox Code Playgroud)

你的编译器看到这样的东西(伪代码):

const [struct Person *]person = NULL;
Run Code Online (Sandbox Code Playgroud)

由于没有任何东西可以const留下,它将令牌降级为正确的struct Person *常数.

我想,这就是为什么我不喜欢用typedef隐藏指针的原因,而我确实喜欢这样的typedef.写作怎么样?

typedef struct Person { ... } Person;
const Person *person; /*< const person */
Person *const pointer; /*< const pointer to mutable person */
Run Code Online (Sandbox Code Playgroud)

对于编译器和人类来说,你应该很清楚,你要做什么.