On Fri, Nov 06, 2015 at 09:24:40PM +0100, Alexander Huemer wrote:
> Hi,
> 
> while fixing some trivial compiler warnings in openbsc I stumbled over 
> this:
> 
> > Making all in abis
> >   CC       abis_test.o
> > abis_test.c: In function ‘test_simple_sw_config’:
> > abis_test.c:68:9: warning: format ‘%u’ expects argument of type ‘unsigned 
> > int’, but argument 2 has type ‘long int’ [-Wformat=]
> >   printf("Start: %u len: %zu\n", descr[0].start - simple_config, 
> > descr[0].len);
> >          ^
> > abis_test.c: In function ‘test_dual_sw_config’:
> > abis_test.c:111:9: warning: format ‘%u’ expects argument of type ‘unsigned 
> > int’, but argument 2 has type ‘long int’ [-Wformat=]
> >   printf("Start: %u len: %zu\n", descr[0].start - dual_config, 
> > descr[0].len);
> >          ^
> > abis_test.c:115:9: warning: format ‘%u’ expects argument of type ‘unsigned 
> > int’, but argument 2 has type ‘long int’ [-Wformat=]
> >   printf("Start: %u len: %zu\n", descr[1].start - dual_config, 
> > descr[1].len);
> >          ^
> > abis_test.c: In function ‘test_sw_selection’:
> > abis_test.c:132:9: warning: format ‘%u’ expects argument of type ‘unsigned 
> > int’, but argument 2 has type ‘long int’ [-Wformat=]
> >   printf("Start: %u len: %zu\n", descr[0].start - load_config, 
> > descr[0].len);
> >          ^
> > abis_test.c:136:9: warning: format ‘%u’ expects argument of type ‘unsigned 
> > int’, but argument 2 has type ‘long int’ [-Wformat=]
> >   printf("Start: %u len: %zu\n", descr[1].start - load_config, 
> > descr[1].len);
> 
> The relevant expression is:
> 
>         descr[1].start - load_config
> 
> and variations thereof.
> descr[1].start is declared include/openbsc/abis_nm.h as:
> 
>         const uint8_t   *start;
> 
> simple_config is declared as:
> 
>         static const uint8_t simple_config[]
>
> So an address is taken and the first element (implicitly) of an uint8 
> array is substracted from it.

No, not at all :)

simple_config, a uint8_t*, is passed to abis_nm_parse_sw_config. After
that, uint8_t *start is actually pointing at a byte within simple_config.
It's a subtraction of two uint8_t* from each other to get a byte offset:

Subtract simple_config's address (the start of the data) from the "start"
pointer's address value, and the result is a byte offset to get from
simple_config to where "start" is pointing. 

The declaration 

         static const uint8_t simple_config[]

yields a uint8_t*, but declaring it with [] allows initializing a static
array. (Also, simple_config == &simple_config == &simple_config[0], all
uint8_t*, which spaces me out every time I come across it.)

Also note the slight counter intuitiveness of subtracting pointers to get
byte offsets: (T*)a - (T*)b == ((uint)a - (uint)b))/sizeof(T), so this case
gives byte offsets precisely because sizeof(uint8_t) == 1...

~Neels

Attachment: signature.asc
Description: Digital signature

Reply via email to