4 ms·
> A null pointer legitimately and usefully points to a zero-sized object. I agree with many points from the article but strongly disagree with this one. It ma
by afc 4y ago
> A null pointer legitimately and usefully points to a zero-sized object.
I agree with many points from the article but strongly disagree with this one.
It makes much more sense to treat a null pointer as an invalid, not present, object. Treating null pointer as an empty string (perhaps by expecting them first N pages to contain just \0 bytes, as various older Unix systems predating Linux did) feels like a recipe to hide bugs.
For example, I want to distinguish the output from getenv of "the variable was found but has an empty value" from "the variable was not defined".
If you have some random struct Foo, it's very clear that a null Foo pointer just means "no valid Foo value" and attempting to dereference it should crash (rather than optimistically return ~random data and naively continuing program execution, making bugs harder to detect).
I expect any reasonable programmer would suggest treating a string (or array of any types) identically.
- mgaunard 4y agoIn C++, std::string_view() refers to an empty string, with a null pointer and size of 0.
- rand_flip_bit 4y agoSadly, this actually isn’t true, and can cause some dangling/use-after-free issues. An empty string_view has a length of zero, but it’s representation might contain a null/non-null pointer + zero or two pointers that “compare equal”. I put compare equal in quotes because pedantically, after delete/free are called, they will not be required to compare equal.
- mgaunard 4y agoSee https://en.cppreference.com/w/cpp/string/basic_string_view/basic_string_view https://en.cppreference.com/w/cpp/string/basic_string_view/b... overload 1. Also it's "its", not "it's".
- dezgeg 4y ago> Treating null pointer as an empty string (perhaps by expecting them first N pages to contain just \0 bytes, as various older Unix systems predating Linux did) feels like a recipe to hide bugs. Empty string is not a 'zero-sized object'. It's an object with size of one byte that is zero.
- leni536 4y agoIt's not an empty string, it's an empty range. The author wrote "zero-sized object". An empty, \0 terminated string is 1 byte. There is nothing worong in treating [NULL, NULL) as a valid, 0-sized range. As a sibling comment pointed out, this is already valid in C++ for std::string_view. Or more appropriately, for std::copy as well.
- asveikau 4y agoBut a lot of APIs take a void* and size_t pair, where one is a buffer and another is a length. It is pretty unreasonable for ptr=NULL, len=0 to be UB, if the code will not follow the pointer when len == 0. TFA says that is the case for some libc functions. I agree that this is unreasonable. Eg. memcpy shouldn't care if pointers it should not follow are invalid; a copy of length 0 ought to be spec'd as a no-op.
- skissane 4y ago> It is pretty unreasonable for ptr=NULL, len=0 to be UB, if the code will not follow the pointer when len == 0. Many of these cases were due to backward compatibility - different pre-existing implementations did different things, everybody wanted to claim conformance to the standard but nobody wanted to change their existing behaviour to do so (potentially breaking their existing application base), so the political compromise was to make them UB. Thankfully, the ISO C standards committee, in recent years, seems less afraid to make breaking changes than they used to be. And many of these UB cases were to placate implementations that are now long-dead-sometimes you’ll find that despite being UB, most or all major contemporary implementations do the same thing, which increases the odds that a future release of the standard might standardise those behaviours. But this is what happens when a programming language gets to be 50 years old.
- none_to_remain 4y agoAuthor didn't say "treat null pointer as an empty string". To treat a C string as empty, I have to dereference the pointer and see that the first byte is \0. If the pointer is 0x0 then I crash. But if I want to copy 0 bytes to or from 0x0, I do not have to dereference 0x0. I would want to spend way too long with the standard before I opined on the correctness of the author's statement, but "zero-sized object" is definitely different from "zero-length string".
- jart 4y agoI think Chris is right. I was able to build the world's tiniest programming language by redefining NULL to be a NUL-terminated string that says "NIL". https://justine.lol/sectorlisp2/#memory https://justine.lol/sectorlisp2/#memory