
Dear Tom,
In message 20140313191814.GB16360@bill-the-cat you wrote:
+struct uuid {
- unsigned int time_low;
- unsigned short time_mid;
- unsigned short time_hi_and_version;
- unsigned char clock_seq_hi_and_reserved;
- unsigned char clock_seq_low;
- unsigned char node[6];
+};
This struct starts with an uint, so it requires alignment on a 32 bit boundary (i. e. an address that is a multiple of 4).
And this needs to be marked as packed since we're using this as a direct representation of things on-disk.
Not really. The arrangement of the elemnts makes sure that there are no inter-element gaps, and even if we had arrays of such structs (which we don;t have) it would work as the struct adds up to a multiple of 32 bits.
+void gen_rand_uuid(unsigned char *uuid_bin) +{
- struct uuid *uuid = (struct uuid *)uuid_bin;
Here you cast a pointer to the (unaligned) character buffer to a struct buffer, which requires alignment.
Potentially unaligned buffer. There's only one caller thus far, and it will be aligned there. We do need to comment that the pointer needs to be aligned.
No. We should rather fix the code such that it works with any alignment. It is trivial here to use a struct uuid on the stack and then use memcpy() to cpy the data from the struct to the buffer - no casting needed anywhere, and no alignment concerns either.
With the struct not packed, it'll be padded out so this works. But looking at how we later use this as I say above, we do need to pack it, and then this will not be safe. Some looping of strncpy into the char buffer, as a char so we whack the rand data in?
I can't see why we would not simply initialize the elements step by step. It's just such a small struct.
Best regards,
Wolfgang Denk