LWN.net Logo

null pointers

null pointers

Posted Mar 19, 2008 17:18 UTC (Wed) by quotemstr (subscriber, #45331)
In reply to: null pointers by vmole
Parent article: Who maintains dpkg?

Name a POSIX system, or better yet, a platform on which dpkg runs, where code and data
pointers are not the same size. Using NULL for function pointers is fine given certain
assumptions, and these days, IMO, one can safely make these assumptions. 


(Log in to post comments)

null pointers

Posted Mar 19, 2008 17:54 UTC (Wed) by vmole (subscriber, #111) [Link]

Once upon a time, people assumed that sizeof(int) == sizeof(_ptr_).

Once upon a time, people assumed that sizeof(int) == sizeof(long).

Once upon a time, people assumed that sizeof(int) == 2 and sizeof(long) == 4.

Once upon a time, people assumed you could dereference NULL (or 0), and its value was 0.

Once upon a time, people assumed that all the world was ASCII.

Times change, and your "safe assumptions" are not so safe anymore.

null pointers

Posted Mar 19, 2008 18:05 UTC (Wed) by quotemstr (subscriber, #45331) [Link]

Assumptions are necessarily for practicality. You assume that cars will stop at red lights
when you cross the street, don't you? You assume that a char has eight bits, don't you?

Standards are simply sets of assumptions we allow programs to make. POSIX implies that using
NULL, with a sensible definition, is okay for every kind of pointer.

Some assumptions are warranted and others not. It's not warranted to assume little-endian byte
ordering, for example, because the choice is arbitrary and still not uniform. OTOH, it is
warranted to assume that pointer types are the same size because they're uniform ally so, and
because there's a strong reason to think that the assumption will hold into the future.

null pointers

Posted Mar 19, 2008 20:20 UTC (Wed) by vmole (subscriber, #111) [Link]

You assume that cars will stop at red lights when you cross the street, don't you?

You obviously don't live in Houston. I'd be dead if I was that careless. (No smiley.)

You assume that a char has eight bits, don't you?

No, why would I? Sure, that's the most common situation, but if I'm actually coding something that requires that (unusual), then I check. Now, I admit that I probably would just error-out, rather than spend the time coding for the unusual situation until I actually needed it.

Sure, we all make assumptions when we have to. But why make an assumption when you can just as easily follow the standard? If you're coding to POSIX, and POSIX really does imply that null-pointer types are all interchangeable, then fine. But the code isn't C standard compliant, and I've spent way too much of my life fixing code full of assumptions about platforms and compilers to have much positive to say about code that doesn't follow appropriate standards.

null pointers

Posted Mar 19, 2008 21:39 UTC (Wed) by quotemstr (subscriber, #45331) [Link]

If you've represented a UTF-8 encoded string with some kind of char array, you've relied on
'char' having at least eight bits.

There is a tradeoff involved in not making assumptions. Say you're writing a portable program
and you don't want to assume AF_UNIX support. You can either use some other IPC mechanism,
likely to be less efficient, or code two versions, one that uses unix-domain sockets and
another that uses something else. Either way, there is an overhead for not assuming AF_UNIX
support, either in runtime overhead or maintenance.

You can add build-time checks of your assumptions, true, but some assumptions hold true so
often that it's often not worth even bothering to check. All I'm arguing is that for
non-embedded systems, all pointers being the same size is the case often enough that it's not
worth it to litter the code with strange casts.

Checking whether the assumption held would be simple enough with something like autoconf, but
there's no reason to clutter the code itself.

null pointers

Posted Mar 19, 2008 22:39 UTC (Wed) by vmole (subscriber, #111) [Link]

Whose talking about littering the code with strange casts? Do you really find:

   somevarargfunc("these", "are", "some", "strings", (char *) NULL);
strange or confusing? Because that's all we're talking about. Any non-varargs function will have a prototype that will take care of this. (At this point someone will pipe-up with the comment that C89 doesn't require prototypes. That's true. But then you have to cast a lot of things, and my argument becomes stronger, not weaker.)

And of course there's a tradeoff in not making assumptions. But the kind of thing you're talking about, such as OS features available, is a whole different level, and no, I don't see anything wrong with assuming (for example) that a program is unix-like specific, and coding it as such, when the cost of doing otherwise is non-trivial. But why this desire to willfully violate a basic standard to save a few characters, when the (not-likely, but could happen) downside is obscure failures and tedious debugging?

Oh, and there's a big difference between "assume char is 8 bits" and "assume char is at *least* 8 bits". The first is an assumption that will eventually bite you, the second is not an assumption at all, but is guaranteed by the C89 standard.

null pointers

Posted Mar 20, 2008 10:19 UTC (Thu) by tfheen (subscriber, #17598) [Link]

Whether C89 requires prototypes or not is irrelevant to dpkg though, as dpkg is using C99.
(--std=gnu99, to be precise.)

null pointers

Posted Mar 19, 2008 21:03 UTC (Wed) by nix (subscriber, #2304) [Link]

It doesn't even hold into the present :(

null pointers

Posted Mar 19, 2008 21:11 UTC (Wed) by quotemstr (subscriber, #45331) [Link]

Can you name an example of a POSIX system for which the assumption does not hold?

null pointers

Posted Mar 19, 2008 21:47 UTC (Wed) by nix (subscriber, #2304) [Link]

Any IA64 or PPC64-based systems. I think HPPA too but can't remember.

(On both these platforms it so happens that data pointers are all the same 
size: but function pointers are larger... and yes this has exposed bugs in 
free software.)

null pointers

Posted Mar 19, 2008 21:57 UTC (Wed) by quotemstr (subscriber, #45331) [Link]

I don't think that's true. See the downthread comments on the same topic. I'd be interested in
knowing what the specific bugs were.

null pointers

Posted Mar 19, 2008 22:18 UTC (Wed) by nix (subscriber, #2304) [Link]

If I could remember, I'd say. I'll have a dig.

null pointers

Posted Mar 28, 2008 22:33 UTC (Fri) by anton (guest, #25547) [Link]

On [PPC64 and IA64] it so happens that data pointers are all the same size: but function pointers are larger.
Not on Linux-PPC64 (and probably not on Linux-IA64, either):
#include <stdio.h>
int main()
{
  printf("%ld %ld\n", sizeof(void *), sizeof(int(*)()));
  return 0;
}
prints
8 8

null pointers

Posted Mar 29, 2008 1:08 UTC (Sat) by nix (subscriber, #2304) [Link]

Oh. My memory is failing me and I can't read simulator source code, it 
seems. (I was *sure* they were examples of arches using a descriptor 
consisting of a data pointer combined with other stuff.)

null pointers

Posted Mar 20, 2008 15:07 UTC (Thu) by lysse (subscriber, #3190) [Link]

> Assumptions are necessarily for practicality... You assume that a char has eight bits, don't
you?

I think that's called "disproving your own argument by contradiction".

null pointers

Posted Mar 19, 2008 20:54 UTC (Wed) by nix (subscriber, #2304) [Link]

Have two, IA64 and PPC64.

Code and data pointers being different sizes is not uncommon: generally, 
in that situation, the data pointer is a plain pointer and the code 
pointer is some sort of descriptor.

null pointers

Posted Mar 19, 2008 21:22 UTC (Wed) by quotemstr (subscriber, #45331) [Link]

No go. How would dlsym() work if that were true? Also, an IA64 function pointer is a pointer to a function descriptor, which is a pair of values -- a pointer to the start of the code and the global pointer to use for that function. The pointer to the descriptor is a normal data pointer, and is what corresponds to the C-level function pointer.

null pointers

Posted Mar 19, 2008 21:48 UTC (Wed) by nix (subscriber, #2304) [Link]

Ah, oops. Forgot about that. (It's tripped me up before, too.)

(I still have memories of pointer sizing bugs in the area of dlsym(), but 
I can't remember what they were.)

null pointers

Posted Mar 20, 2008 3:52 UTC (Thu) by rganesan (subscriber, #1182) [Link]

> Name a POSIX system, or better yet, a platform on which dpkg runs, where 
> code and data pointers are not the same size. Using NULL for function 
> pointers is fine given certain assumptions, and these days, IMO, one can 
> safely make these assumptions. 

I think you guys are missing the point. The issue is not code vs data pointers. The issue is
ptr vs data. A varargs function being passed a NULL pointer needs to be passed (void *) 0 or
(char *) 0 or some pointer. Passing just a 0 which is legal representation for a NULL pointer
in C does not work for 64-bit systems. 0 is a 32-bit quantity, (void *) 0 is a 64-bit quantity
for LP64 (Unix/Linux) as well as P64 (Windows) 64-bit platforms.

Copyright © 2008, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds
Powered by Rackspace Managed Hosting.