C:'const'限定符在使用typedef的参数列表中的含义

gmxoilav  于 2023-03-29  发布在  其他
关注(0)|答案(2)|浏览(106)

当使用typedef和附加限定符时,参数列表的解析是如何工作的?它是否像文本替换一样工作,类似于#define?
示例:

typedef struct Parameters_t * Parameters_pot;
f(const Parameters_pot pars) 
f(Parameters_pot const pars) 

两个函数描述中的参数列表中的'const'限定符是否与数据类型相关,意味着指针指向常量结构?或者'const'的位置是否重要,在第一个函数声明中'const'意味着结构对象是常量,而在第二个声明中它意味着指针是常量?

fkvaft9z

fkvaft9z1#

这不是文本替换。这就是为什么在typedef后面隐藏指针或数组被认为是非常糟糕的做法。这里的两个例子都相当于:
f(struct Parameters_t * const pars)
只是因为它被要求,这里有一个解释正式语言律师的尝试:
C17 6.7.8规定typedef的形式为typedef T type_ident;,其中type_ident是一个类型名“由T中的声明说明符指定的类型”。说明符是复数。为了理解这一点,我们必须回到6.7和6.7.6关于“声明符”和“声明说明符”的内容。
6.7.6说每个声明都可以说是由T D1组成,其中T是声明说明符,D1是声明符。

  • “声明说明符”是你可以写在声明中标识符前面的所有东西,包括存储类说明符(static等)和类型限定符(const等),当然还有类型说明符(int等)。其中几个可以选择存在于同一声明中。

除了存储类说明符,作为一种特殊情况,它们永远不能相互组合(6.7.1)。碰巧的是,typedef算作存储类说明符,所以我们不能在typedef中包含static这样的东西。

  • “declarator”包含标识符和数组符号等。它可以选择性地包含指针的*。这里重要的是*属于declarator。

形式语法(6.7.6)如下:

  • declarator:*
  • pointropt direct-declarator*

...

  • 指针:*

*type-qualifier-listopt
回到typedef T type_ident;,那么所有T都属于该类型,包括使用的任何限定符,指针语法,数组语法等。
因此,如果我们写类似const T的东西,那么const将应用于整个类型T。现在,如果我们有'T',例如const int*“a pointer to const int”,那么const T将因此创建一个const int* const,“a const pointer to const int”。
如果T是一个函数,那么它将试图声明一个无效的“const函数”。
因此,对于typedef struct Parameters_t * Parameters_pot;示例,const应用于struct Parameters_t *类型。
因此f(const Parameters_pot pars)等价于f(struct Parameters_t * const pars)
f(Parameters_pot const pars)也具有相同的等效含义,原因与int constconst int是等效的相同-声明说明符可能出现的顺序在大多数情况下没有指定。

6uxekuva

6uxekuva2#

Parameters_pot是struct Parameters_t * 的别名。所以你的例子是这样的:

f(const struct Parameters_t * pars) the pointer is pointing to a constant structure.
f(struct Parameters_t * const pars) the pointer is constant.

相关问题