【问题标题】:Compile time initialization with const pointer from function使用来自函数的 const 指针进行编译时初始化
【发布时间】:2018-06-05 06:50:05
【问题描述】:

我有一个这样定义的结构:

typedef struct {
    sn74lvc138a_options_t decoder_opts;
    uint32_t pin_int;
    uint32_t pin_rst;
    uint32_t pin_pwr;
    ...
} w5500_options_t;

嵌套结构 sn74lvc138a_options_t 结构如下所示:

static const sn74lvc138a_options_t sn74lvc138a_opts ={
    .decoder_a = DECODER_A_GPIO,
    .decoder_b = DECODER_B_GPIO,
    .decoder_c = DECODER_C_GPIO,
    .decoder_sel = DECODER_SEL_GPIO
};

这两个存储在两个不同的 C 模块中。 C 模块之一(也包含 w5500_options_t 实例的模块)定义了以下函数:

static const sn74lvc138a_options_t* _get_spi_decoder(void) {
    return cpu_samv71_get_sn74lvc138a();  // This is a function from the other C module
}

我希望能够为编译时初始化执行以下操作:

static const w5500_options_t w5500_opts = {
    .pin_int = SOMEVALUE1,
    .pin_rst = SOMEVALUE2,
    .pin_pwr = SOMEVALUE3,
    .decoder_opts = _get_spi_decoder()
};

基本上我想要做的是在初始化块中获取对结构实例的引用。由于引用本身被定义为 const 并且函数返回一个 const 指针,编译器应该能够做到这一点(我使用的是 GCC 和 C99)。

现在的问题是:这是根本不允许的,还是我做错了什么而不允许这样做。我从编译器得到的确切错误消息是“初始化元素不是常量”。

【问题讨论】:

  • 您不能为文件范围或静态变量初始化调用函数。 C++ 允许; C 没有。
  • 请注意,通常不应创建以下划线开头的函数、变量或宏名称。 C11 §7.1.3 Reserved identifiers (部分)说: — 所有以下划线开头的标识符以及大写字母或另一个下划线始终保留供任何使用。 — 所有以下划线开头的标识符在普通名称空间和标记名称空间中始终保留用作具有文件范围的标识符。 另请参阅What does double underscore (__const) mean in C?
  • @JonathanLeffler:该函数被定义为静态并且具有文件范围。在这种情况下使用下划线是错误的吗?不太清楚“普通和标签空间”是什么意思。感谢您对静态变量初始化的关注。
  • 这是一个函数。什么样的功能并不重要。它不能用作静态变量的初始化器。
  • 下划线开头你是如履薄冰。很多人都这样做。许多人侥幸逃脱。标准并没有说你不能这样做,但你不应该这样做。如果你这样做了,你在未来的任何时候都有失败的风险,而且没有办法,只能改变代码,这样它就不会忽视标准给出的建议。

标签: c initialization constants


【解决方案1】:

这是不允许的,因为编译器对你很有帮助。

将与初始化对应的运行时操作视为来自可执行文件的memcpy() 并进入进程堆中的某个位置;这就是你所得到的。一堆位被设置为预定义的模式,没有函数被调用。

【讨论】:

  • 我只是希望,由于该路径中的所有元素都被声明为 const,因此编译器有一种直接的方法可以将该结构仅存储在 ROM 空间中,而不是同时存储在 ROM 和 RAM 中。感谢您提供信息。
  • 我猜一个足够先进的编译器[*] 可以解决这个问题,但由于编写的代码是无效的(有一个函数调用,其中应该有编译时常量数据),它是实现起来不是很直观的优化。
猜你喜欢
  • 2018-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
相关资源
最近更新 更多