【问题标题】:sizeof(array) within array declaration of implicit size隐式大小的数组声明中的 sizeof(array)
【发布时间】:2020-03-30 18:47:32
【问题描述】:

考虑以下常见的数组定义,注意数组本身必须包含总大小:

#define BUFSZ 3
uint8_t buffer[BUFSZ] = {
    BUFSZ, 0xFF, 0x00
}

当您大量更改缓冲区并且它变得足够大以至于跟踪每个更改比每次从头开始计数更容易时,这不是很方便。 当然,这样的事情是可能的:

#define BUFSZ 3
uint8_t buffer[BUFSZ] = {
    sizeof(buffer), 0xFF, 0x00
}

反之亦然

#define BUFSZ 3
uint8_t buffer[] = {
    BUFSZ, 0xFF, 0x00
}

但是完全不需要计数的两者的组合是不可能的:

uint8_t buffer[] = {
    sizeof(buffer), 0xFF, 0x00
}

这导致
invalid application of 'sizeof' to incomplete type 'uint8_t[]' {aka 'unsigned char[]'}
注意我使用的是 arm-none-eabi-gcc 编译器,但这也适用于 gcc。

对于需要在编译时定义一个需要存储其大小的数组的情况,最佳实践是什么?
我想一个选项可能是保留该位置并在运行时设置它,这在我的情况下可以工作,但也可能阻止它保存在只读内存中。

【问题讨论】:

  • 恐怕在 C 中没有办法做到这一点。你能做的最好的事情就是你的第一个例子。此外,[] 情况下的数组大小在编译器完成初始化程序解析之前是不知道的。
  • 根据您的用例,在外部生成此类数组可能是一种选择:使用脚本或单独的程序生成包含数组的数据文件,然后包含该文件。将生成集成到您的构建过程中。
  • 谢谢,很遗憾。是的,对于某些数据来说这是有意义的,尽管这是硬编码的 USB 设置数据,所以现在必须这样做。现在将在运行时用 sizeof 覆盖该位置,至少在积极开发期间是这样。
  • 如果你不害怕宏,你可以编写一个宏,通过在复合数组文字上使用sizeof(a) / sizeof(*a)技巧来确定参数的数量:see here
  • ^^ 我很喜欢这样,需要一些修改来设置特定位置的大小,但它仍然允许类似数组的数据输入

标签: c arrays gcc sizeof


【解决方案1】:
#define  INIT   0xFF, 0x00
#define  SOF(x) (sizeof((char []){x})+1)

char buffer[] =
{
    SOF(INIT) , INIT
};

#define  SOF(name, ...) char name[] = {(sizeof((char []){__VA_ARGS__})+1), __VA_ARGS__}

SOF(buffer,255,0);

【讨论】:

  • 有趣的选项,通过创建一个单独的数组很好地规避了“不完整类型”错误。虽然现在输入数据会很痛苦,但所有这些\
  • @Seneral 或单行版本。查看修改后的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-20
相关资源
最近更新 更多