4 ms·
If you're able to accept ABI breakage or changing the C code, then I don't think any major language which is capable of calling C code is missing support for un
by kbolino 3y ago
If you're able to accept ABI breakage or changing the C code, then I don't think any major language which is capable of calling C code is missing support for unions.
The same cannot be said for varargs, though.
- o11c 3y agoI explicitly refer to untagged unions though, not tagged ones. The lack of a language-known tag is part of the API, not just the ABI. Even library-specific tags should only be considered an incremental upgrade, not the core union support. Yes, it is possible to refactor things like `SDL_Event` to use subclasses instead of unions. But the point is - you shouldn't have to, not at first. And of course, you need to be able to use a union to perform a bitwise cast between float and int. Not some other ad-hoc API; it needs to be trivial to port from C regardless of what the context looks like.
- kbolino 3y agoI'm trying to think of how it would be possible to have memory-safe untagged unions. I don't really think there's a workable solution in the general case, though there might be some specific cases where it works. Undefined behavior is perfectly acceptable for C (though it makes code less portable); it is completely unacceptable in safe languages (outside of unsafe callouts). I'm also not sure why it's necessary to use a union for bitwise conversions. Java and Go, off the top of my head, have safe functions for bitwise int<->float (int32<->float32 in Go) and long<->double (int64<->float64 in Go). Moreover, if I remember correctly, you are only actually allowed to use one case at a time in a C union. If I'm right, then using a union to do bitwise casts is actually undefined behavior in C, even if it almost always works. Put simpler, you cannot write one type into a union then read a different type; you must always read the last type that was written. edit: I dug up my copy of K&R 2/e and yeah, unions are not meant to be used for things like casts. Some supporting text: > A union is a variable that may hold (at different times) objects of different types and sizes, .... (Sec 6.8, p. 147) > Any one of these types may be assigned to u and then used in expressions, so long as the usage is consistent: the type retrieved must be the type most recently stored. It is the programmer's responsibility to keep track of which type is currently stored in a union; the results are implementation-dependent if something is stored as one type and extracted as another. (Sec 6.8, pp. 147-148) In the case of SDL_Event, there actually is a discriminator of sorts. Every case of the union starts with `Uint32 type` and I don't think any case breaks 4-byte alignment on most platforms. With a little compiler support, it would probably be possible to support SDL_Event variables directly in a memory-safe language.