我正在MDK-ARM
环境中编写一个基于状态机的embedded C
代码,该环境使用RealView
(基于ARMCC)编译器。
IDE生成错误:
错误:#28:表达式必须有一个常数值。
代码的一部分如下:
struct wspace
{
struct netimer period;
struct nequeue deferred;
struct nevent *deferred_queue_storage[EPA_EEPROM_QUEUE_SIZE];
struct nepa *producer;
struct event_i2c_transfer transfer;
uint32_t i2c_retry;
uint8_t i2c_buffer[3];
uint32_t address;
uint8_t *raw_buffer;
uint32_t size;
uint32_t idx;
uint32_t max_size;
uint32_t dev_id;
};
static naction state_init_eeprom(struct nsm * sm, const struct nevent * event) {
struct wspace * ws = nsm_wspace(sm);
switch (event->id) {
case NSM_INIT : {
struct nequeue_define deferred_queue =
**NEQUEUE_DEF_INIT(ws->deferred_queue_storage, sizeof(ws->deferred_queue_storage));** // this is the line pointed by compiler
netimer_init(&ws->period);
nequeue_init(&ws->deferred, &deferred_queue);
ws->transfer.super = g_default_event;
ws->transfer.super.producer = nepa_get_current();
ws->transfer.dev_id = EEPROM_I2C_ID;
ws->transfer.timeout_ms = EEPROM_I2C_TIMEOUT_MS;
ws->max_size = 8 * 1024;
ws->dev_id = EEPROM_I2C_ID;
return (naction_transit_to(sm, state_idle));
}
default : {
return (naction_ignored());
}
}
}
重要定义:
#define NEQUEUE_SIZEOF(elements)
(sizeof(struct nevent * [elements]))
#define NEQUEUE_DEF_INIT(storage, size)
{storage, size}
struct nequeue_define
{
struct nevent ** storage;/**<@brief Allocated memory storage */
size_t size; /**<@brief Size of queue in bytes */
};
struct nequeue
{
struct nqueue queue;
#if (CONFIG_REGISTRY == 1)
ncore_reg min;
#endif
#if (CONFIG_API_VALIDATION == 1)
unsigned int signature;
#endif
};
我在这个主题上发现的一切都与这样一个事实有关,即常量变量不能作为初始值设定项分配给数组的元素或结构的成员,即使它以前初始化过。
有人知道如何克服这个问题吗?
您不能在常量表达式中使用变量的内容,并且您的结构initalizer是常量表达式。
而sizeof(ws->deferred_queue_storage)
是可以的,因为它的值可以在编译时确定;ws->deferred_queue_storage
无效,因为该变量的内容可以是任何内容。
解决方案是在分配后使用分配:
struct nequeue_define deferred_queue;
deferred_queue.storage = ws->deferred_queue_storage;
deferred_queue.size = sizeof(ws->deferred_queue_storage);
编译器抱怨NEQUEUE_DEF_INIT(ws->deferred_queue_storage, sizeof(ws->deferred_queue_storage));
中的变量使用情况
您可以像NEQUEUE_DEF_INIT(100, 200)
一样使用它,但不能将变量用作宏参数,因为在这种情况下,在编译之前必须知道它。