4 ms·
Here's some food-for-thought questions: First, a correctness question: - if a struct contains padding, the value of these padding bytes is undefined. What ha
by eqvinox 2y ago
Here's some food-for-thought questions:
First, a correctness question:
- if a struct contains padding, the value of these padding bytes is undefined. What happens if you use such a struct as a key?
And then some integration questions:
- how do you make this typesafe against mixing up 2 distinct uses of hashmaps in the application?
- how do you make this typesafe for its keys and values, i.e. remove accident-prone casts on read access?
- how do you not call the compare and hash functions through function pointers? (Calling through function pointers is both performance relevant as well as a target for exploitation by overwriting the pointer)
(None of these have "nice" answers. But thinking about them is IMHO extremely valuable since these are the most challenging in organizing and engineering an actual codebase itself.)
- hoten 2y ago> - if a struct contains padding, the value of these padding bytes is undefined. What happens if you use such a struct as a key? It's undefined for uninitialized objects. If I understand correctly, when an initializer is provided the padding bits are set to 0. Additionally, setting the whole chunk of memory to 0 w/ memset would work. https://stackoverflow.com/a/37642061/24042444 https://stackoverflow.com/a/37642061/24042444 > - how do you make this typesafe against mixing up 2 distinct uses of hashmaps in the application? Lacking templates, the user of the library could create slim wrapper methods for each type (and coerce to void* to call the underlying hashmap lib); You could still accidentally call the wrong method but it would help a bit. I suppose you could wrap the real hashmap in a new type to help further (so each set of wrapper methods for a given type would be forced to use the same wrapper struct). Alternatively, the library could provide helper macros to accomplish the same.
- eqvinox 2y ago> If I understand correctly, when an initializer is provided the padding bits are set to 0. https://interrupt.memfault.com/blog/c-struct-padding-initialization https://interrupt.memfault.com/blog/c-struct-padding-initial... looks at this (albeit a bit outdated; clang 13 and GCC 11) and claims to see undefined values even when initializers are given, at higher optimization levels > Additionally, setting the whole chunk of memory to 0 w/ memset would work. This seems to be the only thing that can be relied on to work (… sadly) An alternate answer is: don't treat structs as chunks of bytes when the chunk crosses padding (i.e. create functions to hash specific structs) Another alternate answer: remove the padding and add "_pad12[34]" members instead. But then you need to figure out where you actually have padding, which is architecture dependent…