Earlier quoted context omitted.
I work in video games, and very recently we had a sneaky bug in one of our AAA titles(that was already out!), where(in huge simplification) we had a struct that looked like: struct Obj { int foo; bool bar; } then we were storing those in a custom hashmap using these as keys, where the hashing function was basically hashing bits of each stored object, without any awareness of what's in the object. The bug was found wh…
If you rely on code containing undefined behaviour you're in for a world of butthurt sooner rather than later. There is no way in C++ to get at the padding bytes unless you're using undefined behaviour. How does the hash function work? Pointer aliasing using reinterpret_cast? Pointer aliasing using C-style casts? Typing punning through the old union switcheroo?
The Lost Art of Structure Packing (2018)
91–100 of 120 posts
Re: The Lost Art of Structure Packing (2018)
#92It would be nice if there was an annotation that just lets the compiler do all the optimization for me for the cases where I don't care about the memory layout of the struct. Just like the Rust compiler can do without repr(C)
Wait, forgive my ignorance, isn’t this the default? If you don’t care about the memory layout then won’t the compiler reorg / pad structure members to fulfill alignment?
Typically if I define a 8bit as the first element, I need to be certain those 8bits are first even if that wastes three more bytes to align on the next variable.
Re: The Lost Art of Structure Packing (2018)
#93Looks like what he really wants is to use Ada which has had much better support for low-level programming than C. Example: Word : constant := 4; -- storage element is byte, 4 bytes per word type State is (A,M,W,P); type Mode is (Fix, Dec, Exp, Signif); type Byte_Mask is array (0..7) of Boolean; type State_Mask is array (State) of Boolean; type Mode_Mask is array (Mode) of Boolean; type Program_Status_Word is record S…
I keep hoping the Zig developer will do a deep dive on Ada and bring over more of this kind of precise control. A language where I have this kind of control over layout, but can still spell `end record;` as `}`, is ideal for some projects I have in mind.
Re: The Lost Art of Structure Packing (2018)
#94Earlier quoted context omitted.
sizeof(struct foo) is required to return the actual size, including padding, so struct foo foo_inst; memset(&foo_inst, 0, sizeof(foo_inst)); will certainly result in all padding bytes being set to zero.
sizeof will include padding, but there is no need for memset to actually perform a write that cannot be consistently observed.
Re: The Lost Art of Structure Packing (2018)
#95Earlier quoted context omitted.
If you rely on code containing undefined behaviour you're in for a world of butthurt sooner rather than later. There is no way in C++ to get at the padding bytes unless you're using undefined behaviour. How does the hash function work? Pointer aliasing using reinterpret_cast? Pointer aliasing using C-style casts? Typing punning through the old union switcheroo?
I don't have the code in front of me, but something like int hash=0; for(int i=0;i (&obj)+i); return hash; Basically hashing each byte of the memory containing the object, regardless of what the object itself represents. We can argue whether that's a smart thing to do or not, but I wasn't in charge of implementing it - it's a relic from a codebase that's more than a decade old at this point. It's a simple hashing met…
Just pack the struct and be done with it.
Re: The Lost Art of Structure Packing (2018)
#96It would be nice if there was an annotation that just lets the compiler do all the optimization for me for the cases where I don't care about the memory layout of the struct. Just like the Rust compiler can do without repr(C)
Re: The Lost Art of Structure Packing (2018)
#97Earlier quoted context omitted.
Well, the contents of the padding bits is legally observable (with a memcpy for example) so the compiler can't assume they are unovservable.
As far as I understand, padding bits are indeterminate until you observe them via a memcpy into a buffer, at which point they will collapse (only in the buffer) to some arbitrary but now-constant value. Is this correct?
edit: interestingly, Biriba is yet another game in the canasta family, my theory is that different groups were originally playing these differents variants, but when they gained knowledge of the more popular variant (burraco), they started playing it but kept calling it with the original name. I guess that up until the internet era, these games were mostly passed via oral knowledge in casual groups.
edit2: macchiavelli [1] is another very fun game of the same family, but a lot more puzzle solving oriented.
[1] https://en.wikipedia.org/wiki/Machiavelli_(Italian_card_game...
Re: The Lost Art of Structure Packing (2018)
#98Re: The Lost Art of Structure Packing (2018)
#99Earlier quoted context omitted.
If you rely on code containing undefined behaviour you're in for a world of butthurt sooner rather than later. There is no way in C++ to get at the padding bytes unless you're using undefined behaviour. How does the hash function work? Pointer aliasing using reinterpret_cast? Pointer aliasing using C-style casts? Typing punning through the old union switcheroo?
You can trivially get at the padding bytes, just cast to char pointer. Their contents are undefined and there is absolutely no guarantee that they will remain constant, but they're there. Generally you have several possibilities for how to escape this problem, but the simplest is to just add the padding and a static assert that the sizeof the struct is what you expect.
No, their contents has an unspecified value.
Re: The Lost Art of Structure Packing (2018)
#100Earlier quoted context omitted.
If you rely on code containing undefined behaviour you're in for a world of butthurt sooner rather than later. There is no way in C++ to get at the padding bytes unless you're using undefined behaviour. How does the hash function work? Pointer aliasing using reinterpret_cast? Pointer aliasing using C-style casts? Typing punning through the old union switcheroo?
Ok, this will sound stupid then, but is pointer aliasing using casts undefined?