nowox
nowox

Reputation: 29096

How to get the offset of a nested struct member in C?

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

Answers (2)

Jens
Jens

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

Mayazcherquoi
Mayazcherquoi

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

Related Questions