C语言 声明的数组没有大小和常量易失性



我在工作项目中找到了这一行,但我无法理解这一点:

extern const volatile uint8 * const volatile array[];

你能帮我解释一下这条线吗?

首先,省略限定符:

uint8 *array[];

array是一个大小未指定且元素为uint8 *的数组。 换句话说,指向uint8的指针数组。

如果此声明显示为函数的参数,则数组语法实际上是指针的简写。 如果它不是函数参数,而是在文件范围内声明的,则将其作为暂定定义。 完整的定义可能出现在代码中的其他位置,用于指定大小和可选的初始值设定项。 如果不存在其他完整定义,则数组定义为具有 1 个元素。

在讨论声明对限定符的含义之前,让我们先谈谈这些限定符的确切含义。

const限定符可防止代码修改命名对象。 鉴于此声明:

const int x;

这意味着x不能使用例如x = 1进行修改。 涉及指针时,它有点棘手:

const int *x;

这会将x定义为指向const int的指针。 这意味着您可以修改x但不能修改它指向的内容。 所以x = &y是合法的,但不是*x = 1.

int * const x;

这将x定义为指向intconst指针,这意味着你不能修改x但你可以修改它指向的内容。 所以x = &y不合法,但*x = 1合法。

const int * const x;

这会将x定义为指向const intconst指针。 因此,在这种情况下,x及其指向的内容都无法修改。

const int * const x[];

在这里,x是一个数组,其元素const指向const int的指针。 与前面的示例一样,对于每个数组元素,既不能修改数组元素,也不能修改它指向的内容。

现在让我们谈谈volatile. 此限定符告诉编译器,有问题的变量可能会发生不可预测的变化。 从 C 标准第 6.7.3p7 节开始:

具有可变限定类型的对象可以在 实现方式未知或有其他未知方面 影响。 因此,任何提及此类对象的表达都应 严格按照抽象机的规则进行评估, 如 5.1.2.3 中所述。 此外,在每个序列点 对象中最后存储的值应与 抽象机器,除非被未知因素修改 前面提到过。134(什么构成对 具有可变限定类型的对象是实现定义的

134(volatile声明可以用来描述一个对象 对应于内存映射的输入/输出端口或对象 由异步中断函数访问。 行动 在如此声明的对象上,不得由 实施或重新排序,除非规则允许 计算表达式

这意味着volatile对象可能会以编译器不知道的方式更改,因此编译器不应对此变量执行任何优化,实际上应假定该值已在外部更改。

现在继续您的完整声明:

const volatile uint8 * const volatile array[];

这将array声明为一个未指定大小的数组,其元素的类型为uint8 *,其中数组的元素不能被程序修改(即const(,但可以在外部修改(即volatile(,以及这些数组元素指向的内容也不能由程序更改,但可以在外部修改。

最新更新