make it possible to wrapping some handle type (but size != @sizeOf(usize))
Proposal syntax:
// from quickjs
const JsAtom = opaque(u32) {}; // always 32bit
it should behavior similar to enum(u32) { _ }; but won't abuse the type system.
This concept is very similar to a lot of proposals discussed in #1595
But my proposal will not introduce new keywords, and its focus is also different. This proposal only focuses on opaque types of specific sizes, so only numeric types can be enclosed in parentheses.
I think an opaque type "of a specific size" is no longer an opaque type.
@codehz i don't think it's a good idea, especially backing a opaque type with a size will defeat it's original idea of being opaque. Using an integer type will also give its backing store semantics, which isn't ideal as well (as people can and will @bitCast it then).
I think the use case for handles is completly solved with exhaustive enums and isn't a hack at all.
If you need a type that has a size, but unknown content, you can always use extern struct { _opaque: [N]u8 } which isn't really introspectible as well and is "just memory"
@MasterQ32 in fact I want a replacement for const handle = extern enum (u16) { _ } and const handle = u16
The problem with the extern struct is that it may have some special abi rule for struct(in c), like require caller provide buffer(in some c abi)
see https://godbolt.org/z/s99or3
in fact I want a replacement for const handle = extern enum (u16) { _ } and const handle = u16
But why replace something that is already perfectly fine?
The problem with the extern struct is that it may have some special abi rule for struct(in c), like require caller provide buffer(in some c abi)
The same ABI rules will apply to a type that is not known if it is struct or integer ;) A opaque type doesn't convey any information except that it has an address. As soon as you define it as either enum or struct (which is your proposal), you enforce ABI mapping and the same problems arise with either struct or enum ABI
@MasterQ32
extern enum (u16) { _ } is abusing the type system. because it is actually not an enumeration.const handle = u16 cannot define custom function on it(that's why original opaque proposal was made).The same ABI rule
no, extern enum should act as a number in any abi, but struct won't, see godbolt.org/z/s99or3
A opaque type doesn't convey any information except that it has an address
not actually, if you look at the HWND type(and many other windows type), you will find that it is not actually a real pointer, it just a handle that has machine word length(so it is not an address, we just abuse type system again).
so why not extended it to non-machine word type?
we will have two types of opaque type for ffi, one is machine word length (pointer to non-sized opaque), the other is not necessarily machine word length (sized opaque)
Maybe it can be combined into one, make opaque to a machine word length size type, but can be changed to another length.
extern enum (u16) { _ }is abusing the type system. because it is actually not an enumeration.
I don't think so. A handle type is just an enumeration of all possible handle values. Each of them is distinct and can only be equality-compared to other handle values, especially to invalid ones:
const Handle = extern enum (u16) {
invalid = 0,
_
};
extern fn createObject() Handle;
var obj = createObject();
if(obj == .invalid)
return error.InvalidHandle;
There are even better examples out there, for example WinAPI uses handles and several special values that inform the user of different things, like invalid, current and a explicit handle.
You cannot even model these kind of handles with an opaque type (as you have no control over its memory layout)
@MasterQ32 in fact I want a replacement for const handle = extern enum (u16) { _ } and const handle = u16
The problem with the extern struct is that it may have some special abi rule for struct(in c), like require caller provide buffer(in some c abi)
see https://godbolt.org/z/s99or3
This is also a perfect example why your proposal isn't working out. Integers/Enumerations are not structs, but an opaque type doesn't have information how it is represented in memory. They can be pointers, handles, whatever. You are only allowed to have a pointer to them, the only information you have is "that thing has an address and i can use that as its identity."
Most helpful comment
This concept is very similar to a lot of proposals discussed in #1595