I am trying out the offsetof
macro. Is my usage of it with the casts well-defined and correct?
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
enum foo { X, Y, Z };
struct foo_struct {
int32_t x;
int32_t y;
int32_t z;
};
static int offset(enum foo f)
{
switch (f) {
case X:
return offsetof(struct foo_struct, x);
case Y:
return offsetof(struct foo_struct, y);
case Z:
return offsetof(struct foo_struct, z);
}
}
static int32_t get(struct foo_struct *fs, enum foo f)
{
return *(int32_t *)((char *)fs + offset(f));
}
static void set(struct foo_struct *fs, enum foo f, int32_t v)
{
*(int32_t *)((char *)fs + offset(f)) = v;
}
int main(void)
{
struct foo_struct fs;
set(&fs, X, 24601);
set(&fs, Y, 3141);
set(&fs, Z, 42);
assert(get(&fs, X) == 24601);
assert(get(&fs, Y) == 3141);
assert(get(&fs, Z) == 42);
}
The following question only applies if my usage is correct and not UB. Compiling with clang
and -Weverything
, I get the following warnings:
warning: cast from 'char *' to 'int32_t *' (aka 'int *') increases required alignment from 1 to 4 [-Wcast-align]
return *(int32_t *)((char *)fs + offset(f));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: cast from 'char *' to 'int32_t *' (aka 'int *') increases required alignment from 1 to 4 [-Wcast-align]
*(int32_t *)((char *)fs + offset(f)) = v;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Is there any way to disable these in code (i.e. without doing -Wno-cast-align), as my understanding is that in this case they aren’t relevant as we know from the struct layout that the cast is ok.
New contributor
wed1may is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
5