1

Say I have a structure acting as a register map.

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

and I have a few constant addresses for my registers

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

And to make things easier to loop through, I would like to put these in an array

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

When I compile this with gcc and -wAll, I get the following warning for each element in the array. I'm trying to get rid of this warning.

warning: initialization makes pointer from integer without a cast

I could type cast each individual address to reg* but that just seems very verbose. Is there a better way?

2
  • each cell in the array should contain a pointer to an 'object' of type struct regs, however you put in each cell a pointer not to a struct regs Commented Aug 2, 2015 at 7:49
  • Yes, but the register set located at each pointer element in the array is a valid struct regs Commented Aug 2, 2015 at 8:24

3 Answers 3

5

Since your constant addresses are addresses and not just integers, you should just declare them as volatile pointers:

#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 - no more warnings. Plus, defining your ADDRs this way makes them less prone to misuse - you always have to use them as pointers.

Note: here I define them as volatile to prevent the compiler from skipping loads or stores, which can be quite critical for a bare-metal application that has to interface with hardware registers.

Sign up to request clarification or add additional context in comments.

2 Comments

I can also wrap the "volatile void *" for each define in another macro (like ADDR), just to make it slightly less verbose.
Why not make the macros volatile regs *? If these are hardware registers, OP should definitively use stdint.h types, not the standard type names.
2

No, if reg_list is of type regs, the types need to match.

But you could do:

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

and then cast where you use reg_list:

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

Remark: It's quite common nowadays to capitalize type names. To me regs looks like a variable name and I think it would be preferable to write Regs (or regs_t if you want adhere to older style convention).

1 Comment

The code used for this question is not the actual code, although the actual code isn't capitalized either. You make a good point.
2

You can use

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

2 Comments

This works, but I've been trying to avoid having to disable warnings
There is no other way to disable this warning, because of code violates C-language rules for implicit type casting. It is needed to make explicit casting from integer to pointer in code otherwise. Also please note, that you initialize only first two regs elements in your code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.