4 ms·
> The comment was about the position of the second element in the structure, I suppose that this wasn't spelled out in the comment but everyone here knows that
by huhtenberg 9y ago
> The comment was about the position of the second element in the structure, I suppose that this wasn't spelled out in the comment but everyone here knows that the first member of a struct is at the beginning.
Wit beyond measure, fascinating.
union zee_tag {
ptrdiff_t tag;
max_align_t foo;
};
static inline void * variant_cast(void * variant_ptr, ptrdiff_t desired_tag) {
ptrdiff_t * variant_tag = (ptrdiff_t *)variant_ptr;
assert(*variant_tag == desired_tag);
- return (void *)((char *)variant_ptr + sizeof(ptrdiff_t));
+ return (void *)((char *)variant_ptr + sizeof(union zee_tag));
}
Shall I sprinkle some comments or is it OK this way?
> Show me.
@@ -15,6 +15,9 @@
#define is(x, T) ((x)->tag == tag(T))
#define as(x, T) ((struct T *)variant_cast((void *)(x), tag(T)))
+#define union_field(T) struct T _##T
+#define tag_union(x, T) (x)->tag = ((x)->_##T, (ptrdiff_t)&Tag##T)
+
struct SomeOne {
int x;
int y;
@@ -25,17 +28,24 @@
float w;
} TagSomeTwo;
+struct SomeThree {
+ float zz;
+ float ww;
+} TagSomeThree;
+
struct Some {
ptrdiff_t tag;
union {
- struct SomeOne _;
- struct SomeTwo __;
+ union_field( SomeOne );
+ union_field( SomeTwo );
};
};
int main() {
struct Some a = {};
- a.tag = tag(SomeTwo);
+
+ tag_union(&a, SomeTwo);
+ tag_union(&a, SomeThree);
printf("Is `a` tagged as SomeTwo: %d\n", is(&a, SomeTwo));
> Show me a version that adds invariant checking.
An exercise left to the reader.
- klodolph 9y ago> Wit beyond measure, fascinating. I'm flattered that you want to talk about me, but I'd rather talk about the code. > An exercise left to the reader. That's really the only interesting part, isn't it? All the other stuff is just minor bugfixes / bikeshedding. I said "show me" the version of tag() that does the static_assert, and "show me" a version that adds invariant checking (that the cast is possible). Neither of these things have been shown. I'm not claiming it's impossible, just that subjectively, this version is worse than doing things the boring way.
- huhtenberg 9y agoIf you don't understand that tag_union(&a, SomeThree) throwing a compile time error is functionally equivalent to static_assert(), then I see no point in continuing this exchange. Ditto for the invariant checking - OP's original code already covered that with its assert(). In fact, that assert() is what this whole thing is about. All points in your opening "garbage" comment were trivial nitpicks, which would've been fine if you didn't decide to express them by trashing other person's code in an overly confident manner. I don't appreciate that, just as I don't appreciate you trying to wiggle out from this exchange on technicalities.
- klodolph 9y agoYes, you're right, tag_union does throw a compile time error, I didn't read that correctly. By your earlier comment I was primed for a `_Static_assert` and when I didn't see that. I thought it had been left out entirely rather than reimplemented in a different manner. On the subject of tone--I honestly believe that the original code has severe subjective design flaws and objective implementation errors, and since the post was gathering upvotes but no critique I was worried that people believed that the code was correct. There are still some nitpicks about your new version, but these are fairly minor in my view (the use of reserved identifiers is pretty tedious and easily avoided). The remaining non-nitpick, what I consider to be a show-stopper, is that you can't switch on the tag. 90% of the time when I'm using a tagged union, I'm doing switch (evt->type). While we can substitute a chain of if/else, I'm not fond of the ergonomics and I would prefer a traditional enum. This is a subjective trade-off, however. Your responses would have been fine if they were criticisms of my argument or of the tone I took. Perhaps I crossed the line, and you called me on it? But these comments are unacceptable ad hominems: > Oh, the horror. It's C, a language that generally expects you to know what you are doing. > Wit beyond measure, fascinating.