Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: What is the data structure of a NULL? Date: Sun, 29 Dec 2019 13:31:09 -0800 Organization: None to speak of Lines: 146 Message-ID: <87blrqrf8i.fsf@nosuchdomain.example.com> References: <87sgl4rc3w.fsf@nosuchdomain.example.com> <87o8vsqh5l.fsf@nosuchdomain.example.com> <87k16fr9za.fsf@nosuchdomain.example.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: reader02.eternal-september.org; posting-host="e3b117bf55650e4ec854fd7e333c3408"; logging-data="29472"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18pFvk8SSIx4MxSjEI2dMY9" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) Cancel-Lock: sha1:VDuMz8J6tIoD9lcBbTYnT3Cj+bg= sha1:pYgpEDubygHb/YhHIaQfPzCmq6U= Xref: csiph.com comp.lang.c++:70787 Ned Latham writes: > Keith Thompson wrote: >> Ned Latham writes: >> > Keith Thompson wrote: >> > > Ned Latham writes: >> > > > Keith Thompson wrote: >> > > > > T writes: >> > > > > > >> > > > > > In C++, when you make a call to Windows Kernel32.dll >> > > > > > and it wants a NULL for one or more of its parameters, >> > > > > > what exactly is the structure of a NULL? A 32 bit >> > > > > > word full of zeros? >> > > > > >> > > > > You might get better answers if you explained why you want to know. >> > > > > >> > > > > If you're making a call from C++, you can just pass a null pointer >> > > > > value such as nullptr or NULL. The compiler needs to know how >> > > > > it's represented. You probably don't. >> > > > >> > > > But knowing it can be useful, I use (void*) to cast integers and >> > > > unsigned integers for functions that require pointer parameters, >> > > > and if (parm) to test them. >> > > >> > > Why? Can you share some examples? >> > >> > Why? In what way does the above need elucidation? >> >> You indicated that it's useful to know how a null pointer is >> represented. How is it useful? Most of the time, the representation >> doesn't matter. > > Knowing it's useful in that it enables me to use it. I'm about to give up on this conversation, since it seems unlikely to go anywhere useful. 99% of the time, there is no good reason to care in C++ how a null pointer, or any other pointer value, is represented. It's an abstraction. You can write C++ code that uses null pointers, and you haven't done anything unnecessarily tricky, your code will work correctly on implementations with different representations. How exactly does knowing how null pointers are represented make it easier to use them? >> > > If a function takes a pointer parameter, you need to pass a pointer >> > > value to it. There are cases where it might make sense to cast >> > > an integer to void*, but they're rare. >> > >> > Irrelevant. >> >> Irrelevant to what exactly? > > Except for that last phrase "but they're rare", your statement amounts to > an acceptance (inadveratant, I'm sure) of what I'm saying. You agree that > "there are cases"; their rarity or otherwise is irrelevanbt. You've decided that rarity is irrelevant. Perhaps it is for whatever you're talking about (I still haven't quite figured out what that is). I acknowledge, of course, that there are some cases in very low-level code where knowing pointer representation is useful. The rarity of those cases is extremely relevant to what I'm talking about. >> > > If you need to pass a null >> > > pointer, use nullptr or NULL. >> > >> > Why? (void*) (well okay (defined_type*), actually) does perfectly well, >> > and it does away with the clumsiness of switching between constant >> > and variable. >> >> Do you mean "(void*)0"? > > Not particularly. (void*) applies safely to variables on systems where > sizeof(int) == sizeof(void*). What variables? Of what type(s)? Are you saying that something like `(void*)42` is useful? >> Yes, that's a valid null pointer constant, but >> why do you prefer it to NULL or nullptr? What do you mean by "switching >> between constant and variable"? > > Pointer arithmetic. I still don't know the answer to my question. Perhaps an example would help. Please take a moment to consider that I really don't know what you're talking about, and that perhaps that's because you haven't explained it clearly. Pointer arithmetic does not depend on the representation of pointers. It's an abstraction defined in terms of the objects the pointers point to. Of course the implementation depends on the representation, but if you're not writing a compiler you *probably* don't need to care about that. I've worked on systems where this: char *ptr = ...; char *p1 = ptr + 1; char *p2 = (char*)((int)ptr + 1); would give p1 and p2 different values (and sizeof (int) == sizeof (char*)). >> > > (In some low-level code, you might >> > > store pointer values in integers.) >> > >> > Indeed. >> > >> > > As for `if (parm)`, that's >> > > valid for any scalar type. >> > >> > Precisely. >> >> Precisely what? > > It's valid for pointers. If that's useful, use it. Yes, of course. And it has nothing to do with pointer representation. It doesn't support you claim that knowing how pointers are represented is useful. >> If parm is of pointer type, `if (parm)` tests whether >> it's a null pointer or not, regardless of how it's represented. You >> seemed to be using that as an example of why it's useful to know how >> pointers are represented. It isn't. >> >> Perhaps I'm missing something. What exactly was your point? > > I've stated it in every post in this thread. Knowing how NUL is > represented can be useful. It's spelled NULL. I don't dispute that it *can* be useful. I disagree that it's useful in general. In particular, I can write code without knowing or caring how a null pointer is represented, and that will work correctly under different implementations that represent it differently. Languages define abstractions precisely so programmers don't have to worry about the underlying details. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com [Note updated email address] Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */