"null Considered Harmful"

B

Ben Bacarisse

Malcolm McLean said:
In C++ a reference is known to be non-null. But in some ways it's a
bit of a nuisance, because the references always have to be
constructed at the point they come into scope.

Just to be clear, the "might be null" and "can't be null" pointer types
in the post you are replying give you flexibility that references
don't. (That may be tangential to your point, I was not clear what
point you were making.)

<snip>
 
M

Melzzzzz

In C++ a reference is known to be non-null.
But in some ways it's a bit of a nuisance, because the references
always have to be constructed at the point they come into scope.
So we have

class Node
{
Node &link1;
Node &link2;

Node Node()
: link1( what do we put here ?),
link2(same problem)
{
}
};

If you're not careful you end up creating a dummy node. Which ends up
as effectively a null pointer, except the system inherently cannot
catch the bug if you try to use it.

Heh, references are invented because of operator overloading.
Using them instead of pointers is not exactly convenient ;)
 
J

James Kuyper

On Fri, 14 Feb 2014 10:42:57 -0800 (PST)
....
Heh, references are invented because of operator overloading.
Using them instead of pointers is not exactly convenient ;)

If a pointer's value can be set at the point of declaration, and never
modified, it's usually quite trivial to change the code to use a
reference instead; the result is often a substantial simplification of
the code.
 
K

Kaz Kylheku

In C++ a reference is known to be non-null.

In a C++ program that is known to be "strictly conforming" (the C++ equivalent
thereof) that is the case. We indirectly know that the program does no such
thing because we know it to be correct.

In practice, C++ compilers allow references to be bound to dereferenced null
pointers, without diagnostics.

int &ref = *ptr;

There is C++ code out there which depends on this kind of thing:

if (&ref == 0) {
/* reference was bound through a null */
}
 
I

Ian Collins

Kaz said:
In a C++ program that is known to be "strictly conforming" (the C++ equivalent
thereof) that is the case. We indirectly know that the program does no such
thing because we know it to be correct.

In practice, C++ compilers allow references to be bound to dereferenced null
pointers, without diagnostics.

int &ref = *ptr;

There is C++ code out there which depends on this kind of thing:

if (&ref == 0) {
/* reference was bound through a null */
}


That code would be in the same bucket as C code that uses gets...
 
J

Jorgen Grahn

On Fri, 14 Feb 2014 10:42:57 -0800 (PST)
....

Heh, references are invented because of operator overloading.
Using them instead of pointers is not exactly convenient ;)

It is, but not in the context of comp.lang.c so I won't elaborate.

/Jorgen
 
M

Malcolm McLean

Just to be clear, the "might be null" and "can't be null" pointer types
in the post you are replying give you flexibility that references
don't. (That may be tangential to your point, I was not clear what
point you were making.)
I'm not familiar with Mythryl, so I don't know how it handles non-null pointer
types. However I do know C++ - I've recently returned to it because I've
started a new job, and we have to write plug-ins for a program implemented
in C++, so I've no choice but to use it.
One of the problems with references is that they have to be initialised very
early. So in the case of our graph, when the graph is constructed the links
can never be null (for the sake of argument). So there's a strong case for
a non-nullable pointer. But that makes it difficult to construct the graph.
 
K

Kaz Kylheku

That code would be in the same bucket as C code that uses gets...

I'm afraid you're mistaken.

A C++ program which uses null references could could be verified to generate
completely robust machine language that is impervious to bad inputs.

gets is actually dangerous; whereas the above trick is only dangerous on paper.
 
J

Jorgen Grahn

I'm not familiar with Mythryl, so I don't know how it handles non-null pointer
types. However I do know C++ - I've recently returned to it because I've
started a new job, and we have to write plug-ins for a program implemented
in C++, so I've no choice but to use it.

Hm ...
One of the problems with references is that they have to be initialised very
early.

But that's also the /good/ thing about C++ references! Noone said
they would replace pointers; it's just nice that you can use them to
state your intentions more clearly in many (but not all) cases. For
the other cases, you still have pointers.
So in the case of our graph, when the graph is constructed the links
can never be null (for the sake of argument). So there's a strong case for
a non-nullable pointer. But that makes it difficult to construct the graph.

/Jorgen
 
K

Kaz Kylheku

But that's also the /good/ thing about C++ references! Noone said
they would replace pointers; it's just nice that you can use them to
state your intentions more clearly in many (but not all) cases. For
the other cases, you still have pointers.

And this property is still useful if you "abuse" references and bind
them to null. Such a reference cannot be anything but that null over
its entire lifetime (compared to a pointer, which could start non-null
and be inadvertently set to null).
 
K

Kaz Kylheku


The author of this article identifies a problem, but doesn't understand
its real cause. The root cause of the problem is the static type system with
its typed references to objects.

By this, I mean the idea that a value such as a string is
actually manipulated by some "reference to string" pointer-like type
(variables and parameters being statically of this reference type).

Taking such a language as it is, and then disallowing those references from
having a null value will only add to the pain.

The fix is to get rid of these clumsy typed references. The referencing is
hidden as part of the implementation of variable bindings (and other storage
locations). All named and unnamed storage locations simply contain values.

There can be a single value "nil" which is not equal to any other object.

Then, say, passing nil to a string operation isn't a "null reference" problem;
but an ordinary type mismatch, just like passing 123 or 3.0E+3 to a string
function. It's just an object of the wrong type.

Static type inference can catch instances of this problem in programs
which are statically analyzable.

Because it has its own type, you can route it to different methods: to make a
one-argument function that accepts either nil or a string, just write two
methods: one for the string class, and one for the class to which nil belongs
(like the null class in Common Lisp).
 
P

Phil Carmody

This is OT, as it's C++, but wouldn't the compiler be able to
just ignore this whole block, as it's impossible in the absence
of UB, and ignorable in the presence of UB?
That code would be in the same bucket as C code that uses gets...

Worse, I'd say.

Phil
--
What Alice Hill, President at Slashdot Media, writes:
Proven track record innovating and improving iconic websites
(Slashdot.org, ...) while protecting their voice and brand integrity
What Alice Hill means:
2013: Completely fucked up Slashdot, and ignored almost endless
negative feedback about her unwanted changes. 2014: Killed slashdot.
 
N

nick.keighley.zczc

Baby X handles every allocation via bbx_malloc(). It's exactly the same as

malloc(), except that it never returns null. It's not adding any functionality,

and obviously it can't magically provide unlimited memory on demand. It's

just to take null handling out of Baby X.



On the other hand, Baby X makes heavy use of callbacks. Virtually every widget

contains a callback function pointer, and an arbitrary pointer to pass back to

it. Both of these can be null, and it's expected that in certain circumstances

they will be null. For example you sometimes want a callback triggered

whenever the user clicks a radio button, but more often you just want to

query the state of the radio widget when the dialog closes.

If we ban null, we've got to create dummy empty functions, dummy pointers

to pass back to them. This is harder to understand, and harder to write.

not according to the OO people. The NullClass is a recognised design pattern. The claim is it simplifies things!
 
N

nick.keighley.zczc

LMcG> "null Considered Harmful"

LMcG> http://peat.org/2013/12/07/null-considered-harmful/



LMcG> "In almost every software project I've been a part of, the

LMcG> majority of errors I've encountered are caused by unexpected

LMcG> null references. Many are caught at compile or test time, but

LMcG> they always creep though, and few platforms are exempt. They

LMcG> crop up everywhere: web applications, desktop applications,

LMcG> embedded software, game consoles, mobile devices -- almost

LMcG> everywhere there is software, there are null references."



LMcG> I am speechless.



I'm not speechless. He writes like someone who's only ever worked in
Java, and who thinks that Java is the alpha and omega of programming
languages and environments. I see idiots like that pontificating online
daily.

He does have a point that, in Java, the null object is often overloaded
to mean "no object" and "the method you just called encountered an
error." But this is not a flaw in the concept of null; it is a flaw in
the design of Java.

"technical debt" always raises my suspishions
 
N

nick.keighley.zczc

K

Kenny McCormack

dunno but people don't do it!

One of the attributes of what I call a "safe language" is global error
trapping - i.e., like in (most dialects of) BASIC, where any untrapped
error causes a program abort. Then you don't need to check the return
value of every function call (like you do in C).

C is, thus, obviously not a "safe language". And never will be.

Not that there is anything wrong with that...
 
K

Kenny McCormack

One of the attributes of what I call a "safe language" is global error
trapping - i.e., like in (most dialects of) BASIC, where any untrapped
error causes a program abort. Then you don't need to check the return
value of every function call (like you do in C).

C is, thus, obviously not a "safe language". And never will be.

Not that there is anything wrong with that...

And one more comment on this - in the context of "what other languages do".

One language that I use frequently is, by default, like (most dialects of)
BASIC - that is, any (untrapped) error is fatal. But it has a command
(ErrorMode(@OFF)) that makes it like C - where now you have to check every
single function call.

It is an ongoing perennial problem for the support staff that when
beginners find out about ErrorMode, they use it in every program by
default. Because they think that error messages make their programs
"unprofessional"...

With predictable results.

The commonly heard slogan on the support board for this language is:

Using ErrorMode(@OFF) turns a 5 minute debugging job into a 6 month one.

There's a lesson in there regarding C somewhere...

--
"If our country is going broke, let it be from
feeding the poor and caring for the elderly.
And not from pampering the rich and fighting
wars for them."

--Living Blue in a Red State--
 
L

Les Cargill

Kenny said:
And one more comment on this - in the context of "what other languages do".

One language that I use frequently is, by default, like (most dialects of)
BASIC - that is, any (untrapped) error is fatal. But it has a command
(ErrorMode(@OFF)) that makes it like C - where now you have to check every
single function call.

It is an ongoing perennial problem for the support staff that when
beginners find out about ErrorMode, they use it in every program by
default. Because they think that error messages make their programs
"unprofessional"...

With predictable results.

The commonly heard slogan on the support board for this language is:

Using ErrorMode(@OFF) turns a 5 minute debugging job into a 6 month one.

There's a lesson in there regarding C somewhere...

This is why there is the "assert()" construct...
 
M

Malcolm McLean

not according to the OO people. The NullClass is a recognised design pattern.
The claim is it simplifies things!
It's a case of coding riund deficiencies in a language.
If the language doesn't have a concept of "null", you can create it by adding
an "isnull" flag to every object, then checking it in every member function.
It's tedious, but it works.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top