they're all ints why did fds get left out of the typedef club qwq
@navi @humm Why do yall think that the multiplication of integer types is a good thing?
It's boilerplate, it makes the code less clear, it bloats header files, and if I need to serialize it I need to add a sysdep test to know what size it is. And the benefits of having specific integer types are dubious at best, I've never seen a strong argument for them.
What makes you want fd_t and errno_t over int or, if anything, int32_t?
@navi @humm I agree with almost everything here but if it's specified as an int under the hood, there's no reason for it not to be officially an int.
Boilerplate wasn't the right word; I rather mean burden of knowledge. Mental boilerplate.
Where I disagree is on our perception of clarity. copy_range(int fd_in, int fd_out, size_t size is clear enough to me, and doesn't burden the language with typedefs in order to say the same thing; documentation is obtained by clever use of (completely optional in a prototype) variable names.
Again, I think at this point it's just a question of taste.
@navi @humm @SRAZKVT That's exactly what I call boilerplate ð
I don't see much value in this kind of macro that will never change. To me 0 in a fd context is just as readable as STDIN_FILENO while being shorter, so I prefer it - and if the fd context isn't clear, then the function needs to make it clearer. But I'm willing to accept it's a pure question of taste.
(Edit: typo)
@navi @humm Okay that makes sense, but it's in the nature of C to use int as a generic handle, and because it's an int doesn't mean you're going to do arithmetic with it. The integers I do arithmetic with are almost exclusively uint32_t, because 1. I want to know what their range is, and 2. in system programming, I never need negative numbers.
int is terrible for arithmetic for these reasons, and on the other hand it's a pretty good type for a handle: wide enough for all your needs and you don't really care if it's 32 or 64 bits, can use negative numbers for e.g. error values, has an ordering so you can use it as a key for sorting and logarithmic searches, etc.
This is a volcanic take, but I'd be okay with removing arithmetic operations from int (as long as you keep comparisons) and making it a handle-only type ð
@navi @humm @ska For functions returning an fd or -1 on error, I see code check fd >= 0. Or code which checks fd <= 2 to see if it's one of the standard streams. close_range (which I think is a misfeature) works on fds >= first and <= last. poll allows you to easily disable polling one of the fds in the array by setting it to ~fd.
All of these require fds to be a numeric type if not an integer type.
@koorogi @navi @humm I see these more as shortcuts than "official" ways to do things. For errors, there could be an FD_ERROR special value. For standard streams, there could me a macro checking them. For close_range, well, we agree it should not exist. For select (not poll, which takes a list of struct pollfd!) there could be macros to enable or disable an individual fd.
I mean, I agree, fd being a numerical type is practical and I like the fact that it's an int, but I don't think your arguments are the deciding factor.
@koorogi @navi @humm No, they're comparison operators, which have a much lighter requirement than arithmetic operations: they only need an ordered set, whereas arithmetic needs a mathematical group/field/ring.
Substraction + sign check requires a stricter hypothesis than direct comparison between two elements does.
Of course, on a computer, this mathematical difference doesn't really matter, because it's all integers inside anyway, but if we're writing a spec, it's worth knowing how strong you want the guarantees to be.