Live data from Hacker News

Passing nothing is surprisingly difficult

davidben.net

61–70 of 80 posts

Re: Passing nothing is surprisingly difficult

#61

It's obviously too late to change this in Rust's case, but I wonder whether being able to differentiate between None and the empty slice is actually a necessary property in general? There are a bunch of languages where empty arrays are "falsy", and in those it's not recommendable to use the two to differentiate valid states. Feels like the same could apply here

I thought the justification for Rust having an unstable ABI is so such things like binary representations of types could change?

Re: Passing nothing is surprisingly difficult

#62

It’s so silly to talk about C not allowing null on memcpy. That’s a thing the spec says, I guess? The solution is clear: just ignore the C spec. It’s total garbage. Of course you can memcpy between any ptr values if the count is zero and those ptr values don’t have to point to anything.

Better be rolling your own compiler in that case. Or your own memcpy with a different name. UB to pass memcpy to null means after that call, the pointer is assumed to be non-null. So if(ptr) can constant fold. Maybe faster. I'm in agreement with you on this but your compiler probably isn't.

-fno-delete-null-pointer-checks

Re: Passing nothing is surprisingly difficult

#63

Earlier quoted context omitted.

> C99 does not guarantee you can use realloc() in this manner Yes it does. It requires support for reallocing down to zero, which results in an object that is like one that comes from malloc(0). (What some people think is that realloc(x, 0) is equivalent to free(x). It isn't. Resizing down to zero isn't freeing. It might be, if malloc(0) doesn't allocate anything and just returns null. Why some people think realloc(x…

I literally quoted someone from WG14. HN really needs the ability to block trolls.

[deleted]

Re: Passing nothing is surprisingly difficult

#64

Earlier quoted context omitted.

> C99 does not guarantee you can use realloc() in this manner Yes it does. It requires support for reallocing down to zero, which results in an object that is like one that comes from malloc(0). (What some people think is that realloc(x, 0) is equivalent to free(x). It isn't. Resizing down to zero isn't freeing. It might be, if malloc(0) doesn't allocate anything and just returns null. Why some people think realloc(x…

I literally quoted someone from WG14. HN really needs the ability to block trolls.

You quoted someone who stated they are not happy with C23, and deflected personal blame for that issue.

If I'm only trolling, then why, having learned about this, am I having to go into code and make defensive fixes?

Re: Passing nothing is surprisingly difficult

#65

Earlier quoted context omitted.

Mostly, the BSD people think that POSIX and ISO C are just forks of Unix documentation, that are mainly used for making non-Unix systems look Unix-like. BSD comes from real Unix DNA and so following those is optional; whatever direction BSD takes is Unix by definition, as if it's forever 1983.

Interesting. I wonder if that means BSD's compiler toolchain has ignored the strict-aliasing misfire that makes such a mess of the ISO associated ones.

[deleted]

Re: Passing nothing is surprisingly difficult

#66

It’s so silly to talk about C not allowing null on memcpy. That’s a thing the spec says, I guess? The solution is clear: just ignore the C spec. It’s total garbage. Of course you can memcpy between any ptr values if the count is zero and those ptr values don’t have to point to anything.

This is a bad idea if your memcpy starts by adding len to src or dst, since nullptr + 0 is nasal demons in C.

Re: Passing nothing is surprisingly difficult

#67

Earlier quoted context omitted.

Yes. If realloc(ptr, 0) returns a null pointer, you don't know whether that's due to a failure (in which case ptr is still valid) or whether it's the happy case (ptr was freed, and the zero-sized request for replacing it produced a null). Thus you don't know whether ptr is still a valid pointer. If it's valid and you treat it as invalid (hands off), that's a leak. If it's invalid and you treat it as valid (free it),…

I'm not talking about implementations that produce a 'successful' null pointer. I'd consider that a quality-of-implementation issue, in that implementations are responsible for returning non-null on 0-size success in the same way they're responsible for not just stubbing out every single malloc() call, so just assuming that a null output indicates failure is appropriate. (Implementations transitioned ages ago toward…

In my well-informed, expert opinion backed by decades of experience, it would have been best to add this wording:

"When size is zero, the realloc function shall free the original object, regardless of whether allocating the new object is successful, and thus regardless of the value returned."

With a footnote explaining the ambiguity that exists otherwise, and that existed historically.

A small change in some implementations here would be better than taking a wrecking ball to defined behavior.

Re: Passing nothing is surprisingly difficult

#68

I'm dealing with the exact same issues right now in my project, this post is very enlightening. > But suppose we want an empty (length zero) slice. So is there an actual rationale for this? I've written the memory allocator and am in the process of developing the foreign interface. I've been wondering if I should explicitly support zero length allocations. Even asked this a few times here on HN but never got an answe…

It is extremely common to have a collection that might or might not be empty at runtime, and we don’t want to force every programmer who allocates a slice to manually write an alternate code path for the empty case.

Are memory blocks collections though? An empty list or table makes intuitive sense. Does a zero sized memory block make sense? I'm having trouble understanding that. If the memory has size zero, then by definition there is nothing to point to, nothing whose address can be taken.

I definitely see the benefits of well-defined arithmetic on null pointers. As a data type though it seems to me that any pointer could be a zero sized allocation.

Re: Passing nothing is surprisingly difficult

#69

Earlier quoted context omitted.

Mostly, the BSD people think that POSIX and ISO C are just forks of Unix documentation, that are mainly used for making non-Unix systems look Unix-like. BSD comes from real Unix DNA and so following those is optional; whatever direction BSD takes is Unix by definition, as if it's forever 1983.

Interesting. I wonder if that means BSD's compiler toolchain has ignored the strict-aliasing misfire that makes such a mess of the ISO associated ones.

"BSD compiler toolchain" is just a GNU toolchain that is a decade plus old.

It will be probably twenty years before someone programming on BSD will have some code wrongly deleted as unreachable because it comes after realloc(ptr, 0).

They are immune from the damage.

For instance, OpenBSD 6.8 was released in 2020. On that release, gcc reports as 4.2.1, released in 2007.

Re: Passing nothing is surprisingly difficult

#70

Earlier quoted context omitted.

Do you mean that as written? I'd find that extremely surprising, and would in my mind, violate all sorts of safety assumptions, primarily that deref'ing NULL traps¹. E.g., I am pretty sure Go relies on some of the behavior described here: that the 0 page is unmapped, and that accesses will trap. This is why Go code will sometimes SIGSEGV despite being an almost memory-safe language: Go is explicitly depending on that…

Ideally it would be an unmapped trap considering it’s literally how every other runtime works. The next best option is to make it read only. The dumbest option is to make it read/write as that’s going to be a vector for security vulnerabilities.

Security researchers are crafty. I wouldn't give them a read-only page, either. They'll find a way to turn a null-deref with that into an exploit.

"And then we just look for the UID under this NULL pointer — and hey, that's a read-only page of zeros! We're now root." Or something.

Post reply on HN