C错误:表达式必须具有常量值

时间:2012-07-28 16:15:09

标签: c arrays compiler-errors

我正在编写一些嵌入式代码,通过SPI与外部设备连接。该设备有几个不同长度的寄存器,为了帮助保持正确,我已经定义了以下结构

typedef struct
{
    uint16_t    Signed          :1;  // Register is signed or unsigned
    uint16_t    CommLengthBytes :3;  // The width of the register in bytes 
    uint16_t    Address         :12; // Register address
}ts_register;

然后我在源代码中定义了每个寄存器,如下所示

static const ts_register    SAGCYC      = {0, 1, 0x000};
static const ts_register    DISNOLOAD   = {0, 1, 0x001};
static const ts_register    LCYCMODE    = {0, 1, 0x004};
static const ts_register    IRMSA       = {0, 4, 0x31A};
static const ts_register    IRMSB       = {0, 4, 0x31B};
static const ts_register    VRMS        = {0, 4, 0x31C};

我有一个函数,它将指向一个ts_registers数组,并排队读取数组中所有寄存器所需的SPI传输,并调用回调函数来处理回复

当我尝试按照以下方式创建我想要阅读的ts_registers数组时,我的问题出现了:

ts_register regs_to_read[3] = {VRMS, IRMSA, IRMSB};

这会产生错误:“表达式必须具有常量值”3次(每个数组元素一次)。

由于它们被定义为常数,我忽略了什么?

3 个答案:

答案 0 :(得分:6)

  

由于它们被定义为常数,我忽略了什么?

在使用const修饰符声明的C对象中,不是真常量。 const的更好名称可能是readonly - 它的真正含义是编译器不会让更改它。并且您需要使用真常量来初始化具有静态存储的对象(我怀疑regs_to_read是全局的)。

您可以尝试在之前调用的函数中分配regs_to_read,然后再使用该数组。

答案 1 :(得分:2)

const在编译时不会使它们成为常量。让他们#defines和编译器 会很高兴。

答案 2 :(得分:1)

我认为这可能是一个编译器问题,了解您的平台以及如何构建此代码会很有帮助。我只是拿了你的大部分代码,编写它来编译它,并使用gcc在Linux上编译。没有警告。

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>

typedef struct
{
    uint16_t    Signed          :1;  // Register is signed or unsigned
    uint16_t    CommLengthBytes :3;  // The width of the register in bytes 
    uint16_t    Address         :12; // Register address
}ts_register;

int main(int argc, char **argv) {

    static const ts_register    SAGCYC      = {0, 1, 0x000};
    static const ts_register    DISNOLOAD   = {0, 1, 0x001};
    static const ts_register    LCYCMODE    = {0, 1, 0x004};
    static const ts_register    IRMSA       = {0, 4, 0x31A};
    static const ts_register    IRMSB       = {0, 4, 0x31B};
    static const ts_register    VRMS        = {0, 4, 0x31C};

    ts_register regs_to_read[3] = {VRMS, IRMSA, IRMSB};

    return(0);
}

您是否尝试过投射值?它并不总是最好的事情,但会让你解决错误。

您是否考虑过创建#define条目?

另外,请注意在C中需要考虑一些习惯。它们并不总是像你期望的那样表现。