3 ms·
That's interesting. Every project I've worked on has had at least one bug of this form, and typically more than one, where the integer-type indexes into a table
by tom_ 9y ago
That's interesting. Every project I've worked on has had at least one bug of this form, and typically more than one, where the integer-type indexes into a table of integer-type IDs have got mixed up with the integer-type IDs.
You might be surprised how much of a pain in the arse it is to even realise these bugs exist, because during development and initial tests these tables have a nasty habit in many situations of containing IDs that are the same as the index. And when everything is an int, or similar, fixing them can be quite painful too. It just takes one bug in one function for a set of subtly broken workarounds and/or misunderstandings to spread throughout the code. Lots of places where functions take an "id" and then pass it into a function that takes an "index", or vice versa... just what was the intention here? :(
This shit is the worst kind of bug.
My usual solution:
struct ThingID {uint64_t id;};
typedef struct ThingID ThingID;
struct OtherThingID {uint64_t id;};
typedef struct OtherThingID OtherThingID;
And that's it. When at all syntactically inconvenient, it's a sign you're possibly doing the wrong thing.
- mike-cardwell 9y ago"Every project I've worked on has had at least one bug of this form, and typically more than one" Then we have had completely different experiences in software development and are unlikely to agree on the importance of the content in this post.
- tom_ 9y agoQuite! It's supposed to be an alternative viewpoint, nothing more. Thinking about it, maybe I shouldn't have opened with "That's interesting", which here means exactly what it says, but is a phrase sometimes deployed with malicious intent.
- matt_the_bass 9y agoI like your solution.
- JoachimSchipper 9y agoAgree. I've used 'uint64_t thing_id' in somewhat-similar situations, to make it visually obvious which type you're dereferencing. (That is, thing_do(foo.other_thing_id) still compiles, but at least it looks wrong.)