C and C++ could have non_nullable pointers, easily
C and C++ could have non_nullable pointers, easily
Posted Aug 20, 2009 22:19 UTC (Thu) by hppnq (guest, #14462)In reply to: C and C++ could have non_nullable pointers, easily by hummassa
Parent article: Null pointers, one month later
Well, yeah. For ages GCC has supported the nonnull function attribute, used to specify arguments of a function that should not be NULL so you can catch these at compile time.
The problem, however, is that in non-trivial programs you need to be able to dereference pointers that could be NULL even if they should not be NULL. The compiler may not be able to catch all of these situations for you.
Posted Aug 21, 2009 4:45 UTC (Fri)
by njs (subscriber, #40338)
[Link] (11 responses)
Yes, that's no problem. When you set up the sort of type system he or she describes, you include some sort of syntax that lets you get convert a "nullable" pointer into a non-null pointer by checking that it is, in fact, non-NULL. Once it's a non-null pointer, it becomes legal to dereference. (In the OP's sketch they overload the 'if' operator for this, but you could add some sort of extra syntax instead if you want to make it clearer.)
It does mean you can't dereference a maybe-NULL pointer *that is actually NULL*, but... that's the point :-).
Posted Aug 21, 2009 7:17 UTC (Fri)
by nix (subscriber, #2304)
[Link] (5 responses)
I still don't see any robustness benefit here.
(Of course proving that pointers cannot be null at compile time is
Posted Aug 21, 2009 7:48 UTC (Fri)
by dgm (subscriber, #49227)
[Link] (2 responses)
The gotcha is that null pointers are just _one_ type of invalid pointer.
Posted Aug 21, 2009 19:10 UTC (Fri)
by nix (subscriber, #2304)
[Link] (1 responses)
Posted Aug 22, 2009 1:10 UTC (Sat)
by njs (subscriber, #40338)
[Link]
Posted Aug 21, 2009 7:54 UTC (Fri)
by farnz (subscriber, #17727)
[Link]
It's also impossible to verify the C type system; this doesn't stop
compilers from running. The trick is to go for a conservative assessment;
you're not interested in the choices "will sometimes be null/will never be
null", you're interested in "might or might not be null/will never be
null". The second is tractable; imagine an "ifnull( <ptrexpression>
) {
null-block } else { <ptrexpression is now nonnull> nonnull-block }".
By
requiring you to use ifnull to convert nullable pointers to nonnull
pointers whenever you might encounter them, the compiler can force you to
decide how you're going to handle unexpected nulls.
Whenever the compiler isn't sure that a pointer is nonnull, it gives a
compile-time error message. So, examples:
This forces you to handle nulls sanely at some point, or fail to
compile and link properly. Practical code handles nullness at boundary
points, and then passes nonnull pointers around the place, to code which
can assume that they're not null.
Posted Aug 27, 2009 19:35 UTC (Thu)
by hummassa (subscriber, #307)
[Link]
Posted Aug 21, 2009 8:00 UTC (Fri)
by hppnq (guest, #14462)
[Link] (4 responses)
This assumes that pointers do not change, which is only true in the trivial cases. If you want to be completely safe, your only option is to always check, right before using it, that a pointer is not NULL.
And then, by the way, you still have to worry about what will happen it turns out to be pointing to 0x1. ;-)
Posted Aug 21, 2009 22:53 UTC (Fri)
by nix (subscriber, #2304)
[Link] (3 responses)
Posted Aug 21, 2009 23:40 UTC (Fri)
by corbet (editor, #1)
[Link] (2 responses)
Posted Aug 22, 2009 0:34 UTC (Sat)
by nix (subscriber, #2304)
[Link] (1 responses)
... but ERR_PTR() has a somewhat comprehensible reason to exist. The thing
Posted Sep 9, 2009 6:59 UTC (Wed)
by cmccabe (guest, #60281)
[Link]
In higher level languages like OCaml, Java, etc., when you encounter an unrecoverable error in a function, you throw an exception. Then the function has no return value-- control just passes directly to the relevant catch() block.
ERR_PTR is the same thing. Normally, the function would return a foo pointer, but an unrecoverable error happened. So you get an error code instead. As a bonus, if you forget to check for the error code, you get a guaranteed crash (well, if some bonehead hasn't allowed the page starting at address 0 to be mapped). I say "bonus" because the alternative is usually a nondeterministic crash.
C and C++ could have non_nullable pointers, easily
C and C++ could have non_nullable pointers, easily
cannot_convert_null exceptions from the pointer conversion?
impossible in the general case.)
C and C++ could have non_nullable pointers, easily
C and C++ could have non_nullable pointers, easily
compatibility with almost all previous code: this from a language so
conservative that by word-of-dmr the precedence of && and || was
intentionally set wrong so as to avoid breaking code running on three
sites :)
C and C++ could have non_nullable pointers, easily
C and C++ could have non_nullable pointers, easily
int func1( int *pointer )
{
return *pointer; // Compile error here - cannot deference a nullable
}
int func2( int * nonnull pointer )
{
return *pointer; // OK
}
int func3( int * pointer )
{
return func2( pointer ); // Compile error here - even if pointer is
actually non-null.
}
int func4( int * pointer )
{
ifnull( pointer )
return 0;
else
return func3( pointer ); // OK, but func3 still won't compile, as
other callers might use a null pointer.
}
int func5( int * pointer )
{
ifnull( pointer )
return 0;
else
return func2( pointer ); // OK
}
C and C++ could have non_nullable pointers, easily
C and C++ could have non_nullable pointers, easily
Once it's a non-null pointer, it becomes legal to dereference.
I've maintained code that actually went so far as to do this:
C and C++ could have non_nullable pointers, easily
struct blah *foo (...)
{
if (error_1)
return NULL;
if (error_2)
return (struct blah *)1;
if (error 3)
return (struct blah *)2;
/* repeat for ten or so errors */
return /* a real struct blah */;
}
After I'd finished being sick into the keyboard I got a new keyboard and
fixed it so it didn't do that anymore.
Ever seen the kernel ERR_PTR() macro? :)
C and C++ could have non_nullable pointers, easily
C and C++ could have non_nullable pointers, easily
I'm discussing had only half a dozen callers, and half of them ignored the
fact that it might return an error and just blindly dereferenced anyway
(but for all I know the same is true of ERR_PTR()s users).
C and C++ could have non_nullable pointers, easily
