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

Avoiding gcc warning when making an array of pointers to a structure via hardcoded addresses

假设我有一个用作寄存器映射的结构。

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*,但这看起来非常冗长。有没有更好的方法?

不行,如果reg_list是类型regs,类型需要匹配。

但你可以这样做:

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

然后在你使用的地方投射 reg_list:

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

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

您可以使用

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

由于您的常量地址是地址而不仅仅是整数,您应该将它们声明为 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 };

瞧 - 没有更多警告。此外,以这种方式定义您的 ADDR 可以降低它们被滥用的可能性 - 您始终必须将它们用作指针。

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