The Standard allows us to cast pointers to object type to each other if they are suitably aligned. 6.3.2.3(p7)
:
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned68) for the referenced type, the behavior is undefined.
The Standard allows us to copy object representation into char[sizeof(the_object_type)]
6.2.6.1(p4)
:
The value may be copied into an object of type unsigned char [n] (e.g., by memcpy); the resulting set of bytes is called the object representation of the value.
Also, The Standard explicitly states that
Two values (other than NaNs) with the same object representation compare equal, but values that compare equal may have different object representations.
Consider the following code:
struct contains_64_t{
uint64_t value;
};
int main(int args, const char *argv[]){
_Alignas(struct contains_64_t)
char buf_2_64t[2 * sizeof(struct contains_64_t)];
struct contains_64_t c64_1;
c64_1.value = 1;
struct contains_64_t c64_2;
c64_2.value = 2;
memcpy(buf_2_64t, &c64_1, sizeof(c64_1));
memcpy(buf_2_64t + sizeof(c64_1), &c64_2, sizeof(c64_2));
//suitably aligned, ok
struct contains_64_t *c64_ptr = (struct contains_64_t*) buf_2_64t;
printf("Value %"PRIu64"\n", c64_ptr -> value);
}
QUESTION: Is it pedantic to write code like this? If no, what kind of problem we may run into if doing so?
From what I see,
we can cast char*
to struct contains_64_t
since it is suitably aligned. But the problem is that the declared type of buf
is char[2 * sizeof(struct contains_64_t)]
. So formally speaking we cannot access the buf
through an lvalue of type struct contains_64_t *
.
But that would be strange since we have suitably aligned pointer and literally identical object representation. Surely we could declare struct contains_64_t buf[2];
, but the solution would not work in case of struct
containing variably length array
UPD: Would doing such buffer alignment be enough if we assume we are compiling with GCC?