char *myChar = 0;
std::cout
compile because it's undefined behavior?What is wrong with NULL
131–140 of 147 posts
Re: What is wrong with NULL
#132I'm not a c++ expert, but doesn't char *myChar = 0; std::cout compile because it's undefined behavior?
Re: What is wrong with NULL
#133Re: What is wrong with NULL
#134Earlier quoted context omitted.
Sorry, no. You can only pass a stable, property typed Python representation of your left elbow, or the magic unicorn, not the elbow or unicorn itself.
If it quacks like a unicorn then it's still a duck
Ceci n'est pas une corne.
Sometimes a horn is just a cigar.
Re: What is wrong with NULL
#135C++ introduced non-null references. But they didn't enforce them. There are still "I'm so l33t I can use null references" people. The new move semantics use null references for things moved from. C++ is trying to do Rust-like borrow checking without a borrow checker. Errors result in de-referencing null and crashing. Rust doesn't have null, but it has Option , which is often syntactic sugar for null. It's not that nu…
The new move semantics use null references for things moved from. No. When you move the contents out of somewhere like an std::vector instance, that object is left in an undefined but valid state. You're free to continue working with that object (though the only meaningful thing you can usually do without undefined behaviour is destruction or the equivalent of clear ). That's very different from null references.
If p1 is a unique_ptr, and you do
p2 = std::move(p1);
p1's pointer is set to null. Further uses of p1 will fail, or crash, or something. p1.get()
returns the underlying pointer or null, apparently escaping the unique_ptr protection.It's far inferior to Rust's borrow checker.
Re: What is wrong with NULL
#136The mistake is an unsafe null: making every object type carry a value in its domain which says "Oops, though my type says I'm a Foobar, I'm not actually an object, la la la! Have a free exception on me, in your face!" Lisp's NIL is brilliant. It's in its own type, the null type! And it's the only instance of that type. No other type has a null instance. Null references in the language simply reflect the tension betwe…
Though the philosophy is different, I'm not sure I see an advantage for NIL when you just look at the effect it has on a programmer's code. You can still have a "NULL-pointer dereference" in CL, except the error is rephrased as "SYSTEM::%STRUCTURE-REF: NIL is not a structure of type X" or whatever. And you still have to have "(if (not (null x)) ...)" which doesn't do much for you, regardless of the underlying theory.
(defmethod quack ((foo string))
... ;; foo is never anything but a string here.
... ;; definitely not nil!
)
(defmethod quack ((foo null))
... ;; foo is definitely nil here
)
Unlike in languages where you have a String reference that can be null, a CLOS method parameter specialized to a string cannot be NIL!We can also have this piece of minimalism, quite often recurring in Lisp code:
;; yield x if it is not nil, else yield y
(or x y)
Or play hardball: ;; if calculation signals an error,
;; catch it and keep going
(ignore-errors (calculation x))
After programming in Lisp for a while you would never write: (if (not (null x)) ...)
because it is verbose way of expressing: (if x ...)
Every value is its own test for non-nullness, since every value is a generalized boolean which stands for falsehood if it is nil, and truth otherwise.Re: What is wrong with NULL
#137Re: What is wrong with NULL
#138Earlier quoted context omitted.
This is not contrived. (1) A cache returns something or NULL. It's generic; i.e. implementation doesn't care what it is storing: integers, strings, etc. (2) A particular value of interest may be NULL or non-NULL. But now I can no longer use my generic cache and my values of interest together. A very real example of this is Java's Map interface. It's completely up to implementation on how they handle null, making inte…
You're conflating the meaning of NULL in that case. That's not a problem of NULL, you're using NULL to represent multiple different things. You can use exceptions to handle that scenario. cache = {} getFromCache = (key) -> return cache[key] if cache[key]? throw "not found" doSomethingWithValue = (key) -> try value = getFromCache(key) catch value = getValueFromNonCache(key) return _doSomethingWith(value)
Re: What is wrong with NULL
#139It's worth noting that having a NULL, somewhere, is not so much a problem as forcing types to have a NULL. In this respect, e.g. Python and Rust both get it right: while Python has a None, and Rust has std::ptr::null(), an object that is a string cannot be any of those, because those are different types (NoneType and raw pointer, respectively). C's problem is that a string could be null, and there's no syntax for a n…
You can get a None type when you are expecting a String type... that is exactly the bug they are talking about. The fact that Python makes this problem BIGGER by allowing other types as well doesn't make it less bug prone.
I'm not saying static typing has no value, but there are benefits to dynamic typing, and Python embraces its dynamic typing and is designed around it, so none of the problems given in the article really apply.
Re: What is wrong with NULL
#140The mistake is an unsafe null: making every object type carry a value in its domain which says "Oops, though my type says I'm a Foobar, I'm not actually an object, la la la! Have a free exception on me, in your face!" Lisp's NIL is brilliant. It's in its own type, the null type! And it's the only instance of that type. No other type has a null instance. Null references in the language simply reflect the tension betwe…
Well, except that the Lisp's NIL (and Python's None) only works with dynamic types, where you never had any kind of guarantee to start with. C and Haskell for example have a void type, that is not null, and in Haskell has a value. But a static void is completely different from a null.