Reputation: 29096
One solution to print the offset of the checksum
field in the info
struct, is to use the macros typeof
and offsetof
:
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
typedef struct
{
struct {
int a;
} something;
struct {
int a;
int b;
int c[42];
uint32_t checksum;
int padding[10];
} info[2];
// ...
} S;
int main(void)
{
S s;
printf("%lu\n", offsetof(typeof(s.info[0]), checksum));
return 0;
}
Unfortunately, typeof
is not standard, so I am looking for a more convenient way to write the above example without having to declare info
outside from S
.
Why I am trying to do this?
I have a big structure that represent the content of a FLASH memory that represent blocks of information. Each of these blocks have a checksum that I would like to check:
if (s.info[0].checksum != checksum(s.info[0], offsetof(typeof(s.info[0]), checksum))) {
printf("Oops\n");
}
The writing is not portable because of typeof
.
Upvotes: 4
Views: 1679
Reputation: 72639
I don't know why you are thinking a (non-existing in Standard C) typeof
is required. This goes swimmingly with offsetof
if you give the struct a tag (information
):
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
typedef struct
{
struct {
int a;
} something;
struct information {
int a;
int b;
int c[42];
uint32_t checksum;
int padding[10];
} info[2];
// ...
} S;
int main(void)
{
printf("%zu\n", offsetof(S, info[0].checksum));
printf("%zu\n", offsetof(S, info[1].checksum));
printf("%zu\n", offsetof(struct information, checksum));
printf("%zu\n", offsetof(S, info[0].checksum) - offsetof(S, info[0].a));
return 0;
}
Example run:
$ ./a.out
180
400
176
176
BTW, don't bother with typedefs for structs. They are useless. You don't have to believe me, but you can believe Peter van der Linden.
Upvotes: 3
Reputation: 474
Use pointer arithmetic. Get the address of the element, and then subtract that from the address of the structure.
((unsigned char *) &(s.info[0]).checksum - (unsigned char *) &(s.info[0]))
Upvotes: 0