【问题标题】:Array declared without size and const volatile数组声明没有大小和 const volatile
【发布时间】:2018-10-12 12:19:10
【问题描述】:

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

extern const volatile uint8 * const volatile array[];

你能帮我解释一下吗?

【问题讨论】:

  • 看起来不像标准 C..但提供更多上下文
  • 顺便说一句 cconst 是错字吗?
  • 指向常量uint8_t的常量指针数组不完整?我不确定constvolatile 是如何以理智的方式结合在一起的。但是……可能是嵌入式环境。
  • volatile make shure 定义,编译器的任何优化都不会删除该变量;这是必要的,例如当您寻址微处理器上的寄存器时。
  • array[] 在此上下文中表示指向数组的指针。由于已经有一个指针,它现在是一个双指针。我说的对吗?

标签: c arrays constants volatile extern


【解决方案1】:

首先,省略限定符:

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 指向const int 的指针。所以在这种情况下,x 和它所指向的内容都不能被修改。

const int * const x[];

这里,x 是一个数组,其元素是 const 指向 const int 的指针。和前面的例子一样,对于每个数组元素,数组元素和它所指向的元素都不能被修改。

现在让我们谈谈volatile。这个限定符告诉编译器有问题的变量可能会发生不可预测的变化。来自C standard的第6.7.3p7节:

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

134) volatile 声明可用于描述对象 对应于内存映射的输入/输出端口或对象 由异步中断函数访问。行动 在如此声明的对象上,不应被“优化” 实施或重新排序,除非规则允许 评估表达式

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

现在继续你的完整声明:

const volatile uint8 * const volatile array[];

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

【讨论】:

  • 不错的答案:) 一个挑剔,取决于 array 的定义位置,它可能被认为是一个包含 1 个元素的数组,特别是因为它没有 extern 限定符。
  • @nullp0tr 这种行为是非标准的。一些编译器支持它作为扩展,但不是全部。
  • 如果在包含int i[]; 的转换单元的末尾,数组i 仍然具有不完整的类型,则隐式初始化程序会使其具有一个元素,该元素在程序启动时设置为零。这就是标准所说的。
  • @nullp0tr 在某些编译器上,不是全部。 gcc 将接受它,但不接受 MSVC。
  • @nullp0tr 我已经纠正了。我没能找到那一段。我会更新以反映。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 2023-04-08
相关资源
最近更新 更多