Code: Select all
// [CODE BY FIPS @ 4FIPS.COM, (c) 2018 FILIP STOKLAS, MIT-LICENSED]
typedef struct my_buf_c_s {
const uint8_t *data;
size_t size;
} my_buf_c;
typedef struct my_buf_s {
union {
struct {
uint8_t *data;
size_t size;
};
my_buf_c const_view;
};
} my_buf;
#define MY_CONST_CAST(ptr) (&(ptr)->const_view)
void my_buf___mutable_func(my_buf *buf) {
buf->data[0] = 5; // OK: read-write location 'uint8_t *data'
buf->data = NULL; // OK: read-write object 'uint8_t *data'
buf->size = 0; // OK: read-write object 'size_t size'
}
void my_buf___constant_func(const my_buf_c *buf) {
buf->data[0] = 5; // error: read-only location 'const uint8_t *const data'
buf->data = NULL; // error: read-only object 'const uint8_t *const data'
buf->size = 3; // error: read-only object 'const size_t size'
}
int main() {
uint8_t tmp[] = { 0, 1, 2 };
my_buf buf = { .data = tmp, .size=3 };
my_buf___constant_func(&buf); // error: expected 'const my_buf_c *'
my_buf___constant_func(MY_CONST_CAST(&buf)); // OK
my_buf___mutable_func(&buf); // OK
return 0;
}
Follow the discussion on Reddit...