通过硬编码地址创建指向结构的指针数组时避免gcc警告

时间:2015-08-02 07:40:02

标签: c arrays pointers embedded gcc-warning

假设我有一个充当寄存器映射的结构。

typedef struct{
    int reg1;
    int reg2;
} regs;

我的寄存器有一些常量地址

# define ADDR1 0x60000000
# define ADDR2 0x70000000
# define ADDR3 0x80000000
# define ADDR4 0x90000000

为了让事情更容易循环,我想把它们放在一个数组中

regs * reg_list[4] = { ADDR1, ADDR2, ADDR3, ADDR4 };

当我用gcc和-wAll编译它时,我得到了数组中每个元素的以下警告。我试图摆脱这个警告。

warning: initialization makes pointer from integer without a cast

我可以将每个单独的地址输入到reg *但这看起来非常冗长。还有更好的方法吗?

3 个答案:

答案 0 :(得分:5)

由于常量地址是地址而不仅仅是整数,因此您应该将它们声明为volatile指针:

#define ADDR1 ((volatile void *)0x60000000)
#define ADDR2 ((volatile void *)0x70000000)
#define ADDR3 ((volatile void *)0x80000000)
#define ADDR4 ((volatile void *)0x90000000)

typedef struct{
    int reg1;
    int reg2;
} regs;

volatile regs * reg_list[4] = { ADDR1, ADDR2, ADDR3, ADDR4 };

Voila - 没有更多的警告。另外,以这种方式定义ADDR使它们不易被滥用 - 你总是必须将它们用作指针。

注意:这里我将它们定义为volatile,以防止编译器跳过加载或存储,这对于必须与硬件寄存器接口的裸机应用程序来说非常关键。

答案 1 :(得分:2)

不,如果reg_list的类型为regs,则类型需要匹配。

但你可以这样做:

int reg_list[] = { ADDR1, ADDR2, ADDR3, ADDR4 };

然后使用reg_list投射

volatile regs* address = (regs*)reg_list[index];

备注:现在很常见的是将类型名称大写。对我来说regs看起来像一个变量名称,我认为最好是写Regs(或regs_t,如果你想要遵守旧式约定。)

答案 2 :(得分:2)

您可以使用

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-W<warning-text>"
// your code
#pragma GCC diagnostic pop