4 ms·
There was a proposal for a unit type for C++, it would be a zero-sized type just like void except that you could actually use it to declare a variable and pass
by tux3 1y ago
There was a proposal for a unit type for C++, it would be a zero-sized type just like void except that you could actually use it to declare a variable and pass around as a value, like other regular types.
The less serious proposal: have it be `long void`
- magicalhippo 1y agoIn Delphi, and possibly other Pascal variants, you can do this with a type that's just an empty record (struct). It'll have zero size, but you can declare variables of that type, pass it as parameters and such. IIRC things get a bit funky using this in certain situations, so I'm not sure the compiler devs actually considered this or if it's just a happy accident of sorts.
- int_19h 1y agoThe problem is that it's still a nominal type system, so each empty struct is still a different type. A proper unit type has a single value of that type, and it's the same throughout the entire program.
- magicalhippo 1y ago> The problem is that it's still a nominal type system, so each empty struct is still a different type. Fair point, though for me that was a feature when I used it in Delphi. Allowed me to differentiate them when using them as type parameters (generics).
- kragen 1y agoEmpty structs are supported in clang; I think it's a GCC extension to C. This program: #include <stdio.h> typedef struct {} unit; static unit f(unit *p) { return (unit){}; } static void g(unit u) { } int main() { unit a = {}, b = {}; a = b; f(&a); g(b); printf("a is at %lx, b is at %lx, " "sizeof unit is %d\n", (unsigned long)&a, (unsigned long)&b, (int)sizeof(unit)); return 0; } compiles without complaints on my cellphone and produces the output: a is at 7ffb39805b, b is at 7ffb39805a, sizeof unit is 0 So you can declare empty structs as variables, return them, assign them, pass them as parameters, take their addresses, create them in struct literals, and dereference pointers to them. clang is assigning different addresses to different empty-struct local variables, but presumably in an array all of them would have the same address, unlike in C++. I wouldn't be confident that you could malloc them, and I wouldn't be surprised if passing them by value uncovered compiler divergences in the interpretation of the ABI. (I spent most of last night tracking down a bug due to LuaJIT/GCC ABI differences in the implementation of parameter passing.)
- int_19h 1y agoWhy couldn't you malloc them? Malloc doesn't care about types, it just wants the number of bytes, and 0 is a perfectly valid value to pass to malloc. Now, it's unspecified whether malloc will give you back a pointer distinct from all other non-freed allocated blocks or NULL, but if you don't rely on address as identity that is irrelevant.
- kragen 1y agoYou're right, in the standard it's implementation-defined. I mistakenly thought malloc(0) was undefined. That said, it's probably not the best-tested code path in the system library.
- tonyarkles 1y agoAnd correspondingly calling free() on the returned value is also unlikely to be particularly well tested.
- kragen 1y agoWell, unless it's NULL. I'm pretty sure that people call free(0) a lot.
- int_19h 1y agoI mean, these are literally all special values that are explicitly called out in all the relevant standards (both ISO C and POSIX). Anyone who is competent and is writing tests for libc would surely cover that.
- kragen 1y agoProbably malloc(0) is not completely untested, yes. But it's unlikely to be regularly executed by applications.
- Someone 1y ago> Empty structs are supported in clang; I think it's a GCC extension to C. Indeed. See https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Empty-Structures.html https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Empty-Structur.... That page also says “In C++, empty structures are part of the language”, and “G++ treats empty structures as if they had a single member of type char”. I think that means the size of empty structs differs between GCC C and GCC C++.
- cryptonector 1y agoThis would be useful for decoding ASN.1 CHOICEs and open types that contain a NULL option. These should compile to a sum type where the components have values, except that the NULL cases should not.