假设我有一个充当寄存器映射的结构。
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 *但这看起来非常冗长。还有更好的方法吗?
答案 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