Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #29771 > unrolled thread
| Started by | Maciej Labanowicz <m.labanowicz@gmail.com> |
|---|---|
| First post | 2013-01-01 03:45 -0800 |
| Last post | 2013-01-02 10:34 -0800 |
| Articles | 20 on this page of 107 — 11 participants |
Back to article view | Back to comp.lang.c
[union] Pointers to inherited structs are valid ? Maciej Labanowicz <m.labanowicz@gmail.com> - 2013-01-01 03:45 -0800
Re: [union] Pointers to inherited structs are valid ? Barry Schwarz <schwarzb@dqel.com> - 2013-01-01 17:59 -0800
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-02 10:18 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-01 21:06 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-02 10:45 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-02 19:56 -0500
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-03 08:28 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-03 15:31 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-03 20:55 -0500
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-03 21:00 -0500
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-04 12:56 -0500
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-04 12:59 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-06 20:00 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-07 00:47 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-06 23:06 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-07 04:03 -0500
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-07 08:25 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-13 10:34 -0800
Re: Off-Topic: Irritating Posting Patterns Shao Miller <sha0.miller@gmail.com> - 2013-01-13 16:00 -0500
Re: Off-Topic: Irritating Posting Patterns Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-14 12:27 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-07 07:41 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-12 14:52 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-13 15:19 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-14 12:04 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-14 18:52 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-16 00:01 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-16 05:43 -0500
Re: [union] Pointers to inherited structs are valid ? Geoff <geoff@invalid.invalid> - 2013-01-16 09:01 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-16 18:32 -0500
Re: [union] Pointers to inherited structs are valid ? Geoff <geoff@invalid.invalid> - 2013-01-16 17:32 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-16 20:57 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-17 07:55 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-17 16:47 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-18 08:41 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-18 15:53 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-18 17:38 -0800
Re: [union] Pointers to inherited structs are valid ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-19 02:31 +0000
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-18 23:15 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-19 20:03 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-20 02:19 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-20 07:57 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-20 15:25 -0500
Re: [union] Pointers to inherited structs are valid ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-20 23:58 +0000
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-20 21:30 -0500
Re: [union] Pointers to inherited structs are valid ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-21 02:53 +0000
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-21 00:05 -0500
Re: [union] Pointers to inherited structs are valid ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-21 16:31 +0000
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-21 14:07 -0500
Re: [union] Pointers to inherited structs are valid ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-21 21:05 +0000
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-21 17:13 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-21 16:11 -0800
Re: [union] Pointers to inherited structs are valid ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-22 04:59 +0000
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-22 01:05 -0500
Re: [union] Pointers to inherited structs are valid ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-22 14:53 +0000
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-22 08:38 -0800
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-21 20:53 -0800
Re: [union] Pointers to inherited structs are valid ? Philip Lantz <prl@canterey.us> - 2013-01-22 00:58 -0800
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-22 08:40 -0800
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-22 23:32 -0800
Re: [union] Pointers to inherited structs are valid ? Philip Lantz <prl@canterey.us> - 2013-01-23 23:21 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-24 04:53 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-25 10:49 -0800
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-22 08:25 -0800
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-22 23:41 -0800
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-21 13:32 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-21 17:46 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-22 07:43 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-22 16:07 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-22 14:15 -0800
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-22 14:31 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-22 21:32 -0500
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-23 17:17 -0500
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-23 19:49 -0500
Re: [union] Pointers to inherited structs are valid ? Geoff <geoff@invalid.invalid> - 2013-01-23 18:55 -0800
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-24 11:01 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-24 14:11 -0500
Re: [union] Pointers to inherited structs are valid ? Geoff <geoff@invalid.invalid> - 2013-01-22 17:51 -0800
Re: [union] Pointers to inherited structs are valid ? Philip Lantz <prl@canterey.us> - 2013-01-20 16:48 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-20 21:33 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-21 09:23 -0800
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-20 17:07 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-20 22:20 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-20 22:02 -0800
Re: [union] Pointers to inherited structs are valid ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-21 07:00 +0000
Re: [union] Pointers to inherited structs are valid ? James Kuyper <jameskuyper@verizon.net> - 2013-01-21 08:17 -0500
Re: [union] Pointers to inherited structs are valid ? Dr Nick <nospam-4@temporary-address.org.uk> - 2013-01-21 14:13 +0000
Re: [union] Pointers to inherited structs are valid ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-21 14:12 +0000
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-21 08:20 -0800
Re: [union] Pointers to inherited structs are valid ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-21 20:41 +0000
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-21 12:37 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-21 12:17 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-21 16:33 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-21 15:50 -0800
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-21 19:45 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-22 00:18 -0500
Re: [union] Pointers to inherited structs are valid ? Keith Thompson <kst-u@mib.org> - 2013-01-22 08:01 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-18 23:02 -0500
Re: [union] Pointers to inherited structs are valid ? Philip Lantz <prl@canterey.us> - 2013-01-19 01:28 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-19 12:08 -0500
Re: [union] Pointers to inherited structs are valid ? Geoff <geoff@invalid.invalid> - 2013-01-21 09:27 -0800
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-21 12:46 -0500
Re: [union] Pointers to inherited structs are valid ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-21 20:48 +0000
Re: [union] Pointers to inherited structs are valid ? Geoff <geoff@invalid.invalid> - 2013-01-21 18:52 -0800
Re: [union] Pointers to inherited structs are valid ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-22 04:07 +0000
Re: [union] Pointers to inherited structs are valid ? Shao Miller <sha0.miller@gmail.com> - 2013-01-21 23:15 -0500
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-16 10:59 -0800
Re: [union] Pointers to inherited structs are valid ? Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-02 10:34 -0800
Page 5 of 6 — ← Prev page 1 2 3 4 [5] 6 Next page →
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-20 17:07 -0800 |
| Message-ID | <lntxqb738t.fsf@nuthaus.mib.org> |
| In reply to | #30412 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/20/2013 10:57, Keith Thompson wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>>
>>> Which of these most closely resembles the pointer value 0x0000000C in
>>> this Windows scenario?:
>>>
>>> 1. A trap representation for some pointer type, invoking UB when read
>>> 2. A valid value for some pointer type; pointing to an object
>>> 3. A null pointer; pointing to no object, invoking UB when dereferenced
>>>
>>> If it doesn't compare equal to 'NULL', then it doesn't appear to match
>>> any of these. But if we can fuzz our way from Standard theory to
>>> real-world practice, we might note some similarities to #3.
>>
>> It could easily be #1. For example, if a type `struct foo` has a
>> member `bar` at offset 12 (0xC), and a `struct foo*` object `ptr`
>> that has a null pointer value, then `&(ptr->bar)` could easily have
>> a representation that looks like 0x0000000C.
>>
>
> It could be #1, but it isn't #1 in this Windows scenario.
I believe it is.
> Using such a
> pointer value doesn't yield undefined behaviour until it's dereferenced.
Yes, it does. Concretely:
int main(void) {
struct foo {
char c[12];
int i;
};
struct foo *fptr = NULL;
int *iptr = &(fptr->i);
return 0;
}
The evaluation of the expression `&(fptr->i)` has undefined behavior.
If you disagree, please show me where the standard defines its
behavior.
If the observed behavior is that the representation 0x0000000C is stored
in `iptr`, that doesn't mean the behavior is defined.
> It'll still compare as unequal with valid pointer values, can still be
> assigned to a pointer, etc.
It happens to do so in the implementation we're discussing, and probably
in most implementations.
>> [...]
>>
>>> (By the way, I've asked in another forum about possible documentation
>>> for NULL_CLASS_PTR_DEREFERENCE, although I don't know if you or anyone
>>> else cares.)
>>
>> The name NULL_CLASS_PTR_DEREFERENCE wouldn't necessarily refer to
>> a *null pointer*.
>
> It depends on the definition. For the C definition, if it doesn't
> compare equal to 'NULL', then it's probably not a null pointer, as you
> pointed out earlier.
A pointer that doesn't compare equal to NULL *definitely* isn't a null
pointer, by the definition of pointer equality in N1570 6.5.9p6.
(Unless the program's behavior is undefined for other reasons, in which
case anything goes.)
> For WinDbg users, it probably is. Hopefully I'll
> find out just what Microsoft has to say about it.
I don't believe so. As far as I can see, the only evidence you've
presented that this thing is a "null pointer" is the identifier
"NULL_CLASS_PTR_DEREFERENCE".
What I believe that name implies is that the pointer value whose
representation looks like 0x0000000C was most likely created as
the result of a null pointer. It doesn't imply that 0x0000000C
is itself a null pointer. Nobody other than you is saying that.
(Unless you can produce some Microsoft documentation that uses the
phrase "null pointer" -- with no other words between "null" and
"pointer" -- to refer to such a pointer value.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-20 22:20 -0500 |
| Message-ID | <kdic5n$ful$1@dont-email.me> |
| In reply to | #30426 |
On 1/20/2013 20:07, Keith Thompson wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>> On 1/20/2013 10:57, Keith Thompson wrote:
>>> Shao Miller <sha0.miller@gmail.com> writes:
>>>>
>>>> Which of these most closely resembles the pointer value 0x0000000C in
>>>> this Windows scenario?:
>>>>
>>>> 1. A trap representation for some pointer type, invoking UB when read
>>>> 2. A valid value for some pointer type; pointing to an object
>>>> 3. A null pointer; pointing to no object, invoking UB when dereferenced
>>>>
>>>> If it doesn't compare equal to 'NULL', then it doesn't appear to match
>>>> any of these. But if we can fuzz our way from Standard theory to
>>>> real-world practice, we might note some similarities to #3.
>>>
>>> It could easily be #1. For example, if a type `struct foo` has a
>>> member `bar` at offset 12 (0xC), and a `struct foo*` object `ptr`
>>> that has a null pointer value, then `&(ptr->bar)` could easily have
>>> a representation that looks like 0x0000000C.
>>>
>>
>> It could be #1, but it isn't #1 in this Windows scenario.
>
> I believe it is.
>
I'm very glad you think so. I guess that means it resembles Geoff's
explanation of "trap representations" (not to be confused with the C
definition).
>> Using such a
>> pointer value doesn't yield undefined behaviour until it's dereferenced.
>
> Yes, it does. Concretely:
>
> int main(void) {
> struct foo {
> char c[12];
> int i;
> };
>
> struct foo *fptr = NULL;
>
> int *iptr = &(fptr->i);
>
> return 0;
> }
>
> The evaluation of the expression `&(fptr->i)` has undefined behavior.
> If you disagree, please show me where the standard defines its
> behavior.
>
> If the observed behavior is that the representation 0x0000000C is stored
> in `iptr`, that doesn't mean the behavior is defined.
>
My mistake. I should have either stated that I was talking about a
fuzzy, as-observed version of "undefined behaviour", or should have
called it "unexpected behaviour". You are obviously right.
>> It'll still compare as unequal with valid pointer values, can still be
>> assigned to a pointer, etc.
>
> It happens to do so in the implementation we're discussing, and probably
> in most implementations.
>
Sure.
>>> [...]
>>>
>>>> (By the way, I've asked in another forum about possible documentation
>>>> for NULL_CLASS_PTR_DEREFERENCE, although I don't know if you or anyone
>>>> else cares.)
>>>
>>> The name NULL_CLASS_PTR_DEREFERENCE wouldn't necessarily refer to
>>> a *null pointer*.
>>
>> It depends on the definition. For the C definition, if it doesn't
>> compare equal to 'NULL', then it's probably not a null pointer, as you
>> pointed out earlier.
>
> A pointer that doesn't compare equal to NULL *definitely* isn't a null
> pointer, by the definition of pointer equality in N1570 6.5.9p6.
> (Unless the program's behavior is undefined for other reasons, in which
> case anything goes.)
>
I don't quite understand your use of "definitely" when I had said "If it
doesn't compare equal to 'NULL', then it doesn't appear to match any of
these. But if we can fuzz our way from Standard theory to real-world
practice..." Was this unclear?
But anyway, sure. So you'd say that this dissimilarity weighs enough
that it's closer to #1, and that it's not particularly relevant or
interesting to ask which of the three is a close match, because of the
earlier undefined behaviour. Ok!
As I mentioned before, one of the difficulties for a _programmer_ is
that sometimes _they_get_ these pointers from OS functions, without
having obviously invoked C's UB. Because they can read, assign, and
pass these pointers without unexpected behaviour, it's not like a
signalling NaN, or an integer with improper parity.
>> For WinDbg users, it probably is. Hopefully I'll
>> find out just what Microsoft has to say about it.
>
> I don't believe so. As far as I can see, the only evidence you've
> presented that this thing is a "null pointer" is the identifier
> "NULL_CLASS_PTR_DEREFERENCE".
>
> What I believe that name implies is that the pointer value whose
> representation looks like 0x0000000C was most likely created as
> the result of a null pointer. It doesn't imply that 0x0000000C
> is itself a null pointer. Nobody other than you is saying that.
> (Unless you can produce some Microsoft documentation that uses the
> phrase "null pointer" -- with no other words between "null" and
> "pointer" -- to refer to such a pointer value.)
>
I don't know what you think I'm trying to prove. Are you pointing out
that when I said "WinDbg absolutely calls it a null pointer," I haven't
backed that up?
When programming for the Windows NT kernel, if a pointer is C's 'NULL'
or 0x0000000C, it crashes the computer when it is used for indirect
access, as neither refers to a valid C object. Reading, storing,
passing these values do not crash the computer. What is the practical
difference for an NT driver developer? That they don't compare as equal
with value but only with behaviour? Comparing with 'NULL' yields a
false negative relative to the goal of indirect access. No?
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-20 22:02 -0800 |
| Message-ID | <lnip6r6pkg.fsf@nuthaus.mib.org> |
| In reply to | #30435 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/20/2013 20:07, Keith Thompson wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>> On 1/20/2013 10:57, Keith Thompson wrote:
>>>> Shao Miller <sha0.miller@gmail.com> writes:
>>>>>
>>>>> Which of these most closely resembles the pointer value 0x0000000C in
>>>>> this Windows scenario?:
>>>>>
>>>>> 1. A trap representation for some pointer type, invoking UB when read
>>>>> 2. A valid value for some pointer type; pointing to an object
>>>>> 3. A null pointer; pointing to no object, invoking UB when dereferenced
>>>>>
>>>>> If it doesn't compare equal to 'NULL', then it doesn't appear to match
>>>>> any of these. But if we can fuzz our way from Standard theory to
>>>>> real-world practice, we might note some similarities to #3.
>>>>
>>>> It could easily be #1. For example, if a type `struct foo` has a
>>>> member `bar` at offset 12 (0xC), and a `struct foo*` object `ptr`
>>>> that has a null pointer value, then `&(ptr->bar)` could easily have
>>>> a representation that looks like 0x0000000C.
>>>>
>>>
>>> It could be #1, but it isn't #1 in this Windows scenario.
>>
>> I believe it is.
>
> I'm very glad you think so. I guess that means it resembles Geoff's
> explanation of "trap representations" (not to be confused with the C
> definition).
I'm not going to go back in this thread to figure out what Geoff's
explanation of "trap representations" is supposed to be.
[...]
>>>>> (By the way, I've asked in another forum about possible documentation
>>>>> for NULL_CLASS_PTR_DEREFERENCE, although I don't know if you or anyone
>>>>> else cares.)
>>>>
>>>> The name NULL_CLASS_PTR_DEREFERENCE wouldn't necessarily refer to
>>>> a *null pointer*.
>>>
>>> It depends on the definition. For the C definition, if it doesn't
>>> compare equal to 'NULL', then it's probably not a null pointer, as you
>>> pointed out earlier.
>>
>> A pointer that doesn't compare equal to NULL *definitely* isn't a null
>> pointer, by the definition of pointer equality in N1570 6.5.9p6.
>> (Unless the program's behavior is undefined for other reasons, in which
>> case anything goes.)
>
> I don't quite understand your use of "definitely" when I had said "If it
> doesn't compare equal to 'NULL', then it doesn't appear to match any of
> these. But if we can fuzz our way from Standard theory to real-world
> practice..." Was this unclear?
There's nothing fuzzy about any of this. A pointer value is a null
pointer if and only if it compares equal to NULL.
> But anyway, sure. So you'd say that this dissimilarity weighs enough
> that it's closer to #1, and that it's not particularly relevant or
> interesting to ask which of the three is a close match, because of the
> earlier undefined behaviour. Ok!
>
> As I mentioned before, one of the difficulties for a _programmer_ is
> that sometimes _they_get_ these pointers from OS functions, without
> having obviously invoked C's UB. Because they can read, assign, and
> pass these pointers without unexpected behaviour, it's not like a
> signalling NaN, or an integer with improper parity.
The C standard does not define the behavior of OS functions. Therefore
a call to an OS function has undefined behavior.
>>> For WinDbg users, it probably is. Hopefully I'll
>>> find out just what Microsoft has to say about it.
>>
>> I don't believe so. As far as I can see, the only evidence you've
>> presented that this thing is a "null pointer" is the identifier
>> "NULL_CLASS_PTR_DEREFERENCE".
>>
>> What I believe that name implies is that the pointer value whose
>> representation looks like 0x0000000C was most likely created as
>> the result of a null pointer. It doesn't imply that 0x0000000C
>> is itself a null pointer. Nobody other than you is saying that.
>> (Unless you can produce some Microsoft documentation that uses the
>> phrase "null pointer" -- with no other words between "null" and
>> "pointer" -- to refer to such a pointer value.)
>
> I don't know what you think I'm trying to prove. Are you pointing out
> that when I said "WinDbg absolutely calls it a null pointer," I haven't
> backed that up?
I don't recall you using those exact words, but yes, if you're saying
that WinDbg calls it a null pointer, you haven't backed it up.
Are you in fact claiming that WinDbg calls this a "null pointer"? If
so, please prove it.
> When programming for the Windows NT kernel, if a pointer is C's 'NULL'
> or 0x0000000C, it crashes the computer when it is used for indirect
> access, as neither refers to a valid C object.
So there's some similarity of behavior between a null pointer
(0x00000000 for this implementaiton) and a particular non-null pointer
representation (0x0000000C).
> Reading, storing,
> passing these values do not crash the computer.
One of the myriad possible consequences of undefined behavior.
> What is the practical
> difference for an NT driver developer? That they don't compare as equal
> with value but only with behaviour? Comparing with 'NULL' yields a
> false negative relative to the goal of indirect access. No?
No.
Ignoring for the moment the fact that you can't create or access
that value without having invoked undefined behavior:
The expression `(void*)0x0000000C == NULL` yields 0 (false).
This is not a "false negative"; it's a perfectly correct result
indicating that `(void*)0x0000000C` is not a null pointer.
If you want to determine whether a given pointer value may be safely
dereferenced, comparing it to NULL is not the way to do that.
Please be clear: what exactly are you claiming?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-21 07:00 +0000 |
| Message-ID | <kdip34$73f$1@speranza.aioe.org> |
| In reply to | #30441 |
Keith Thompson <kst-u@mib.org> wrote: (snip) >> When programming for the Windows NT kernel, if a pointer is C's 'NULL' >> or 0x0000000C, it crashes the computer when it is used for indirect >> access, as neither refers to a valid C object. > So there's some similarity of behavior between a null pointer > (0x00000000 for this implementaiton) and a particular non-null pointer > representation (0x0000000C). (snip) > The expression `(void*)0x0000000C == NULL` yields 0 (false). > This is not a "false negative"; it's a perfectly correct result > indicating that `(void*)0x0000000C` is not a null pointer. I would try memcpy() of the 0x0000000C into a pointer variable, and then compare it to NULL. > If you want to determine whether a given pointer value may be safely > dereferenced, comparing it to NULL is not the way to do that. > Please be clear: what exactly are you claiming? -- glen
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2013-01-21 08:17 -0500 |
| Message-ID | <kdjf51$moi$1@dont-email.me> |
| In reply to | #30443 |
On 01/21/2013 02:00 AM, glen herrmannsfeldt wrote: > Keith Thompson <kst-u@mib.org> wrote: ... >> So there's some similarity of behavior between a null pointer >> (0x00000000 for this implementaiton) and a particular non-null pointer >> representation (0x0000000C). > > (snip) > >> The expression `(void*)0x0000000C == NULL` yields 0 (false). >> This is not a "false negative"; it's a perfectly correct result >> indicating that `(void*)0x0000000C` is not a null pointer. > > I would try memcpy() of the 0x0000000C into a pointer variable, > and then compare it to NULL. How? NULL is the name of a macro which must expand into a null pointer constant. It therefore cannot be an lvalue (at least in C - in C++ the rules are different), and therefore cannot be compared using memcpy(). I suppose you could define two pointer variables, store 0xC into one, and the expansion of NULL into the other. However, The result of storing NULL into a pointer variable need not have a unique representation; it could sometimes be represented by 0, and other times by 0xC. The results could easily vary depending upon the type of the pointer variable. Less likely, but still permitted by the standard, is the possibility that you get a different null pointer representation each time the assignment is executed. More importantly, why would you do it that way? The standard says nothing about what the results of that comparison should be, and the results of that comparison have nothing to do with the defined behavior of null pointers. The only testable behavior associated uniquely with null pointers is that they all compare equal to each other, and unequal to any pointer to an actual object or function. Now, if two valid pointers of the same type have the same representation, they must compare equal, but the converse is not true. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Dr Nick <nospam-4@temporary-address.org.uk> |
|---|---|
| Date | 2013-01-21 14:13 +0000 |
| Message-ID | <87wqv6ipy0.fsf@temporary-address.org.uk> |
| In reply to | #30451 |
James Kuyper <jameskuyper@verizon.net> writes: > On 01/21/2013 02:00 AM, glen herrmannsfeldt wrote: >> Keith Thompson <kst-u@mib.org> wrote: > ... >>> So there's some similarity of behavior between a null pointer >>> (0x00000000 for this implementaiton) and a particular non-null > pointer >>> representation (0x0000000C). >> >> (snip) >> >>> The expression `(void*)0x0000000C == NULL` yields 0 (false). >>> This is not a "false negative"; it's a perfectly correct result >>> indicating that `(void*)0x0000000C` is not a null pointer. >> >> I would try memcpy() of the 0x0000000C into a pointer variable, >> and then compare it to NULL. > > How? NULL is the name of a macro which must expand into a null pointer > constant. It therefore cannot be an lvalue (at least in C - in C++ the > rules are different), and therefore cannot be compared using memcpy(). That's true. But then nothing can be compared using memcpy. Once you've done the copy you can just use == to do the comparison. > More importantly, why would you do it that way? The standard says > nothing about what the results of that comparison should be, and the > results of that comparison have nothing to do with the defined > behavior of null pointers. Well he was asking about a particular implementation as I read it. So doing it this way would help to find out whether his hypothesis was correct or not. That sounds quite a good reason to me. > The only testable behavior associated uniquely with null pointers is > that they all compare equal to each other, and unequal to any pointer > to an actual object or function. Which seems to suggest that several different bit patterns could all be valid null pointers. So it his question (which, my memory may be failing, seems to be "I'm seeing 0x000000C where I'd expect to see a null pointer, I wonder if it's because there are several different null pointers used for some compiler/implementation magic") doesn't sound entirely bonkers.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2013-01-21 14:12 +0000 |
| Message-ID | <0.18acdbd39184b596feb1.20130121141207GMT.87a9s27hhk.fsf@bsb.me.uk> |
| In reply to | #30451 |
James Kuyper <jameskuyper@verizon.net> writes: > On 01/21/2013 02:00 AM, glen herrmannsfeldt wrote: >> Keith Thompson <kst-u@mib.org> wrote: > ... >>> So there's some similarity of behavior between a null pointer >>> (0x00000000 for this implementaiton) and a particular non-null pointer >>> representation (0x0000000C). >> >> (snip) >> >>> The expression `(void*)0x0000000C == NULL` yields 0 (false). >>> This is not a "false negative"; it's a perfectly correct result >>> indicating that `(void*)0x0000000C` is not a null pointer. >> >> I would try memcpy() of the 0x0000000C into a pointer variable, >> and then compare it to NULL. > > How? NULL is the name of a macro which must expand into a null pointer > constant. It therefore cannot be an lvalue (at least in C - in C++ the > rules are different), and therefore cannot be compared using memcpy(). Presumably that last "memcpy"is a typo. You presumably meant "and therefore cannot be compared using memcmp()" but why do you think that's what glen herrmannsfeldt (sic) meant? He is suggesting using memcpy to get the desired representation into a pointer object and then using == to see if it compares equal to a null pointer. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-21 08:20 -0800 |
| Message-ID | <lna9s27bju.fsf@nuthaus.mib.org> |
| In reply to | #30451 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 01/21/2013 02:00 AM, glen herrmannsfeldt wrote:
>> Keith Thompson <kst-u@mib.org> wrote:
> ...
>>> So there's some similarity of behavior between a null pointer
>>> (0x00000000 for this implementaiton) and a particular non-null pointer
>>> representation (0x0000000C).
>>
>> (snip)
>>
>>> The expression `(void*)0x0000000C == NULL` yields 0 (false).
>>> This is not a "false negative"; it's a perfectly correct result
>>> indicating that `(void*)0x0000000C` is not a null pointer.
>>
>> I would try memcpy() of the 0x0000000C into a pointer variable,
>> and then compare it to NULL.
>
> How? NULL is the name of a macro which must expand into a null pointer
> constant. It therefore cannot be an lvalue (at least in C - in C++ the
> rules are different), and therefore cannot be compared using memcpy().
I think you've misread what glen wrote (memcpy vs. memcmp?). I believe
he meant something like this:
uintptr_t x = 0x0000000C;
void *ptr;
memcpy(&ptr, &x, sizeof ptr);
if (ptr == NULL) { ... }
But I don't think glen's suggestion is particularly relevant to
the current discussion. It would be for an implementation in which
pointer-to-integer conversion did something other than just copying
the bits, but I don't believe the implementation we're dealing with
(Microsoft's) does that.
The standard permits all sorts of exotic pointer behavior:
null pointers with representations other than all-bits-zero,
pointer conversions that do something other than just copying
or reinterpreting the representation, equality operators that
do something other than a simple bit-by-bit comparison, etc.
And any of those things could lead to a pointer with the same
representation as the integer 0x0000000C being a null pointer.
As far as I know, Microsoft's implementation doesn't do any of
these things; a pointer value with an all-bits-zero representation
is the one and only null pointer for a given pointer type, a pointer
whose representation looks like 0x0000000C is not a null pointer, and
nothing in Microsoft's documentation refers to it as a null pointer.
(Code that dereferences a pointer with that representation is
reasonably assumed, by the debugger, to be the result of referring
to a member of a structure "pointed to" by a null pointer.)
Or perhaps I've misunderstood the point Shao Miller is trying
to make.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-21 20:41 +0000 |
| Message-ID | <kdk95i$dpd$1@speranza.aioe.org> |
| In reply to | #30459 |
Keith Thompson <kst-u@mib.org> wrote:
(snip, someone wrote)
>>>> The expression `(void*)0x0000000C == NULL` yields 0 (false).
>>>> This is not a "false negative"; it's a perfectly correct result
>>>> indicating that `(void*)0x0000000C` is not a null pointer.
(then I wrote)
>>> I would try memcpy() of the 0x0000000C into a pointer variable,
>>> and then compare it to NULL.
>> How? NULL is the name of a macro which must expand into a null pointer
>> constant. It therefore cannot be an lvalue (at least in C - in C++ the
>> rules are different), and therefore cannot be compared using memcpy().
> I think you've misread what glen wrote (memcpy vs. memcmp?). I believe
> he meant something like this:
> uintptr_t x = 0x0000000C;
> void *ptr;
> memcpy(&ptr, &x, sizeof ptr);
> if (ptr == NULL) { ... }
Yes.
> But I don't think glen's suggestion is particularly relevant to
> the current discussion. It would be for an implementation in which
> pointer-to-integer conversion did something other than just copying
> the bits, but I don't believe the implementation we're dealing with
> (Microsoft's) does that.
Yes, but if you wanted to test that, even if you don't believe
it very likely, seems to me that would work.
I might also test 0x0C000000 in case someone got the endianness
wrong.
> The standard permits all sorts of exotic pointer behavior:
> null pointers with representations other than all-bits-zero,
> pointer conversions that do something other than just copying
> or reinterpreting the representation, equality operators that
> do something other than a simple bit-by-bit comparison, etc.
> And any of those things could lead to a pointer with the same
> representation as the integer 0x0000000C being a null pointer.
> As far as I know, Microsoft's implementation doesn't do any of
> these things; a pointer value with an all-bits-zero representation
> is the one and only null pointer for a given pointer type, a pointer
> whose representation looks like 0x0000000C is not a null pointer, and
> nothing in Microsoft's documentation refers to it as a null pointer.
> (Code that dereferences a pointer with that representation is
> reasonably assumed, by the debugger, to be the result of referring
> to a member of a structure "pointed to" by a null pointer.)
As far as I know, too, but then I never looked. Well, I haven't
used any MS compilers for long enough that I didn't have any
reason to look.
> Or perhaps I've misunderstood the point Shao Miller is trying
> to make.
Does seem that it could be useful for a (person using a) debugger
to know where an unexpected NULL pointer came from. The cost isn't
all that high, though you would probably have to do it consistently.
(Someone might link to a non-debug version of a library).
-- glen
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-21 12:37 -0500 |
| Message-ID | <kdjuce$paf$1@dont-email.me> |
| In reply to | #30441 |
On 1/21/2013 01:02, Keith Thompson wrote: > Shao Miller <sha0.miller@gmail.com> writes: >> >> Was this unclear? > > There's nothing fuzzy about any of this. A pointer value is a null > pointer if and only if it compares equal to NULL. > Ok, I miscommunicated, then. I agree with your notion of a null pointer. >> What is the practical >> difference for an NT driver developer? That they don't compare as equal >> with value but only with behaviour? Comparing with 'NULL' yields a >> false negative relative to the goal of indirect access. No? > > No. > > Ignoring for the moment the fact that you can't create or access > that value without having invoked undefined behavior: > Minor nit-pick: Why not? One can modify the object representation. Wouldn't we have to decide that it's a trap representation before suggesting undefined behaviour? > The expression `(void*)0x0000000C == NULL` yields 0 (false). > This is not a "false negative"; it's a perfectly correct result > indicating that `(void*)0x0000000C` is not a null pointer. > Which is why I wrote "relative to the goal of indirect access." > If you want to determine whether a given pointer value may be safely > dereferenced, comparing it to NULL is not the way to do that. > So true! Windows NT has 'MmIsAddressValid' and some other methods. However, this isn't recommended. It seems pretty common in NT that there are functions taking an "optional" pointer value. The cheapest way to test would be 'if (!ptr)'. But if the caller passes 0x0000000C, we most likely will crash. > Please be clear: what exactly are you claiming? > Nothing much; sorry. Let me try to make some fun definitions, deriving from the C ones (plus an omitted definition of "debugger"): - Debug representation: An object representation which provides information to a debugger. A debug representation can represent the same possibilities as an indeterminate value (an unspecified value or a trap representation). - Nasty representation: A trap representation for a given type which, when read by an lvalue expression with that type, causes the program to terminate and provides an implementation-defined prompt for a debugging opportunity with a debugger. - VA32: Any pointer type with a representation that is 32 bits and which has no trap representations. - Unsafe pointer: Any pointer having a VA32 type and having a value that does not refer to any object. If such a pointer value is used in an attempt to access the stored value of a pointed-to object, the behaviour is undefined. - Lull pointer: An unsafe pointer having a value that compares unequal with a null pointer and having a debug representation which, when interpreted by a debugger, suggests (but does not guarantee) that a recent operation expected a non-null pointer and was provided with a null pointer. Such a pointer can lull a program into a false sense of safety for future operations because it compares unequal with a null pointer. Nevertheless, a lull pointer may be used for all purposes, except that the note in the description for "unsafe pointer" still applies. After Geoff's summary of what we might call "debug representations," I thought I remembered 0x0000000C being another one. I wondered if it might carry status information, in particular. Mr. Philip Lantz' explanation makes it likely that it is what we might call a "lull pointer". I shouldn't've argued with you that it wasn't a trap representation; that was a mistake. All I meant was that it didn't resemble what we might call a "nasty representation". A lull pointer is an unsafe pointer. An unsafe pointer has a VA32 type. A VA32 type has no trap representations. A nasty representation is a trap representation. So: A lull pointer cannot have a nasty representation, but still has a debug representation. But who cares? 8-)} -- - Shao Miller -- "Thank you for the kind words; those are the kind of words I like to hear. Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-21 12:17 -0800 |
| Message-ID | <lny5fm5m0w.fsf@nuthaus.mib.org> |
| In reply to | #30464 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/21/2013 01:02, Keith Thompson wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>>
>>> Was this unclear?
>>
>> There's nothing fuzzy about any of this. A pointer value is a null
>> pointer if and only if it compares equal to NULL.
>>
>
> Ok, I miscommunicated, then. I agree with your notion of a null pointer.
>
>>> What is the practical
>>> difference for an NT driver developer? That they don't compare as equal
>>> with value but only with behaviour? Comparing with 'NULL' yields a
>>> false negative relative to the goal of indirect access. No?
>>
>> No.
>>
>> Ignoring for the moment the fact that you can't create or access
>> that value without having invoked undefined behavior:
>
> Minor nit-pick: Why not? One can modify the object representation.
> Wouldn't we have to decide that it's a trap representation before
> suggesting undefined behaviour?
Good point. Yes, you can modify the representation of a pointer object
without undefined behavior:
int *p
*(uintptr_t*)&p = 0x0000000C;
Some, but not all, operations that result in such a pointer value have
undefined behavior.
>> The expression `(void*)0x0000000C == NULL` yields 0 (false).
>> This is not a "false negative"; it's a perfectly correct result
>> indicating that `(void*)0x0000000C` is not a null pointer.
>
> Which is why I wrote "relative to the goal of indirect access."
Comparing a pointer to NULL, if you don't know in advance that it's
either a null pointer or a valid pointer to some object, does not meet
"the goal of indirect access". The phrase "relative to the goal of
indirect access" is meaningless in this context, or just plain wrong.
You might as well talk about "comparing an integer to zero relative to
the goal of determining whether it's even".
>> If you want to determine whether a given pointer value may be safely
>> dereferenced, comparing it to NULL is not the way to do that.
>>
>
> So true! Windows NT has 'MmIsAddressValid' and some other methods.
> However, this isn't recommended. It seems pretty common in NT that
> there are functions taking an "optional" pointer value. The cheapest
> way to test would be 'if (!ptr)'. But if the caller passes 0x0000000C,
> we most likely will crash.
>
>> Please be clear: what exactly are you claiming?
>>
>
> Nothing much; sorry. Let me try to make some fun definitions, deriving
> from the C ones (plus an omitted definition of "debugger"):
>
[snip]
> - VA32: Any pointer type with a representation that is 32 bits and
> which has no trap representations.
What makes you think that 32-bit pointers on MS Windows have no
trap representations? `(void*)0x0000000C` almost certainly is a
trap representation for the implementation in question. (I'm using
the phrase "trap representation" as the C standard uses it; I lack
interest in any other meanings *unless* some documentation uses
that exact phrase with a different meaning.)
> - Unsafe pointer: Any pointer having a VA32 type and having a value
> that does not refer to any object. If such a pointer value is used in
> an attempt to access the stored value of a pointed-to object, the
> behaviour is undefined.
Such a pointer value is either a null pointer or a trap representation.
[...]
> But who cares? 8-)}
I no longer do. Whatever relevant claims you were making, you've now
quietly backed away from them. We could have avoided wasting a great
deal of time if you'd done so sooner.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-21 16:33 -0500 |
| Message-ID | <kdkc6k$mo8$1@dont-email.me> |
| In reply to | #30472 |
On 1/21/2013 15:17, Keith Thompson wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>> On 1/21/2013 01:02, Keith Thompson wrote:
>>> The expression `(void*)0x0000000C == NULL` yields 0 (false).
>>> This is not a "false negative"; it's a perfectly correct result
>>> indicating that `(void*)0x0000000C` is not a null pointer.
>>
>> Which is why I wrote "relative to the goal of indirect access."
>
> Comparing a pointer to NULL, if you don't know in advance that it's
> either a null pointer or a valid pointer to some object, does not meet
> "the goal of indirect access". The phrase "relative to the goal of
> indirect access" is meaningless in this context, or just plain wrong.
> You might as well talk about "comparing an integer to zero relative to
> the goal of determining whether it's even".
>
status_t some_func(input_t * input, output_t ** output) {
output_t * new_item;
status_t status;
/* Do stuff. Populate 'new_item', 'status' */
if (output) {
/* Caller wants to refer to the result */
*output = new_item;
}
return status;
}
Here, if 'output' does not compare equal to a null pointer, we'll
attempt indirection on it. If the caller passed an argument for
'output' which they believed to be one of {null pointer, pointer to an
object}, then our test here yields a false positive for the latter if
what they actually passed was the third possibility: A non-null pointer
to no object.
>> - VA32: Any pointer type with a representation that is 32 bits and
>> which has no trap representations.
>
> What makes you think that 32-bit pointers on MS Windows have no
> trap representations? `(void*)0x0000000C` almost certainly is a
> trap representation for the implementation in question. (I'm using
> the phrase "trap representation" as the C standard uses it; I lack
> interest in any other meanings *unless* some documentation uses
> that exact phrase with a different meaning.)
>
Well I didn't quite say that. I was referring to a particular subset of
32-bit pointers. I would certainly consider the representation
0x00000001 to be a trap representation for an 'int *' in 32-bit Windows.
For VA32 (which would correspond to 'void *', 'char *', etc.), the
reason I would think that is that I've over a decade of use, I guess. I
could be wrong! But here's a starting-point, perhaps:
http://msdn.microsoft.com/en-us/library/k26sa92e.aspx
>> - Unsafe pointer: Any pointer having a VA32 type and having a value
>> that does not refer to any object. If such a pointer value is used in
>> an attempt to access the stored value of a pointed-to object, the
>> behaviour is undefined.
>
> Such a pointer value is either a null pointer or a trap representation.
>
Wait, are you saying that any pointer that does not match one of {null
pointer, points to an object} must necessarily be a trap representation?
>> But who cares? 8-)}
>
> I no longer do. Whatever relevant claims you were making, you've now
> quietly backed away from them.
I haven't intentionally backed away from any claims. I wish I knew what
claims you might be referring to.
If you're asking about "null pointer", I thought Mr. Philip Lantz
already answered that when he said: "This traps in the debugger, and the
debugger reports a "null pointer dereference" at address 0x0000000c."
> We could have avoided wasting a great
> deal of time if you'd done so sooner.
>
I really don't know what you're talking about. Here's my recollection
(quotes aren't actual quotes, but interpretations):
Me: "I thought null pointers having 0x0C as the least-significant byte
was \"a thing,\" too, but now I can't remember having seen that
documented anywhere."
You: "I'm fairly sure Microsoft uses all-bits-zero for null pointers."
Me: "Yes I didn't mean via the strict C definition, but via a practiced
usage of the term, with Microsoft."
You: "Null pointers and trap representations aren't the same thing."
Me: "I'm talking about a pointer value that behaves like a null pointer."
You: "Does it compare equal to 'NULL'?"
Me: "Good point; no, it doesn't. But it still doesn't point to any
object and only invoked undefined behaviour once used for indirection.
That makes it similar to a null pointer, in my view. What do you think?"
You: "It seems more like a trap representation."
Me: "(Well, it isn't, strictly speaking...)"
My last one shouldn't've followed so closely behind the question before
it, because the question was confusing. I don't know if there's a
problem other than confusion. I hope not.
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-21 15:50 -0800 |
| Message-ID | <lnlibm5c4e.fsf@nuthaus.mib.org> |
| In reply to | #30480 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/21/2013 15:17, Keith Thompson wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>> On 1/21/2013 01:02, Keith Thompson wrote:
>>>> The expression `(void*)0x0000000C == NULL` yields 0 (false).
>>>> This is not a "false negative"; it's a perfectly correct result
>>>> indicating that `(void*)0x0000000C` is not a null pointer.
>>>
>>> Which is why I wrote "relative to the goal of indirect access."
>>
>> Comparing a pointer to NULL, if you don't know in advance that it's
>> either a null pointer or a valid pointer to some object, does not meet
>> "the goal of indirect access". The phrase "relative to the goal of
>> indirect access" is meaningless in this context, or just plain wrong.
>> You might as well talk about "comparing an integer to zero relative to
>> the goal of determining whether it's even".
>
> status_t some_func(input_t * input, output_t ** output) {
> output_t * new_item;
> status_t status;
>
> /* Do stuff. Populate 'new_item', 'status' */
>
> if (output) {
> /* Caller wants to refer to the result */
> *output = new_item;
> }
> return status;
> }
>
> Here, if 'output' does not compare equal to a null pointer, we'll
> attempt indirection on it. If the caller passed an argument for
> 'output' which they believed to be one of {null pointer, pointer to an
> object}, then our test here yields a false positive for the latter if
> what they actually passed was the third possibility: A non-null pointer
> to no object.
Right, because, as I said, checking whether a pointer is null does not
reliably check whether it may be dereferenced. It's a false negative
for the question "May I safely dereference this pointer?". It's not a
false negative for the question "Is this a null pointer?"
The test yields a false negative because it's not a valid test for what
it's trying to test. (No such valid test is possible in portable C.)
>>> - VA32: Any pointer type with a representation that is 32 bits and
>>> which has no trap representations.
>>
>> What makes you think that 32-bit pointers on MS Windows have no
>> trap representations? `(void*)0x0000000C` almost certainly is a
>> trap representation for the implementation in question. (I'm using
>> the phrase "trap representation" as the C standard uses it; I lack
>> interest in any other meanings *unless* some documentation uses
>> that exact phrase with a different meaning.)
>
> Well I didn't quite say that. I was referring to a particular subset of
> 32-bit pointers. I would certainly consider the representation
> 0x00000001 to be a trap representation for an 'int *' in 32-bit Windows.
Yes, you did quite say that. You said the pointer type "has no trap
representations".
> For VA32 (which would correspond to 'void *', 'char *', etc.), the
> reason I would think that is that I've over a decade of use, I guess. I
> could be wrong! But here's a starting-point, perhaps:
>
> http://msdn.microsoft.com/en-us/library/k26sa92e.aspx
That looks a lot like the C Standard's requirements for pointer
conversions, with some extra information about how Microsoft's compiler
performs such conversions. Unlike the standard, it doesn't mention trap
representations.
>>> - Unsafe pointer: Any pointer having a VA32 type and having a value
>>> that does not refer to any object. If such a pointer value is used in
>>> an attempt to access the stored value of a pointed-to object, the
>>> behaviour is undefined.
>>
>> Such a pointer value is either a null pointer or a trap representation.
>>
>
> Wait, are you saying that any pointer that does not match one of {null
> pointer, points to an object} must necessarily be a trap representation?
I believe so, yes.
Given a pointer value that is neither a null pointer nor a pointer to an
object, what criteria would cause you to claim that it's *not* a trap
representation?
>>> But who cares? 8-)}
>>
>> I no longer do. Whatever relevant claims you were making, you've now
>> quietly backed away from them.
>
> I haven't intentionally backed away from any claims. I wish I knew what
> claims you might be referring to.
>
> If you're asking about "null pointer", I thought Mr. Philip Lantz
> already answered that when he said: "This traps in the debugger, and the
> debugger reports a "null pointer dereference" at address 0x0000000c."
I don't remember that particular statement. It's been a long thread.
/* Let struct foo have a member m at offset 12 (0xc) */
struct foo *ptr = NULL;
do_something_with(foo->m);
The evaluation of `foo->m` has undefined behavior because the value of
`foo` is a null pointer. It's likely that the generated code will take
the value stored in `foo` (0x00000000), add the offset 12 to it
(yielding 0x0000000c), and then attempt to dereference the resulting
pointer value. If the program is being executed under the debugger,
this is likely to cause a trap. The debugger sees an attempt to
dereference address 0x0000000c and, quite reasonably, infers that it was
probably the result of accessing a member of a structure or class, at an
offset of 12 bytes, via a null pointer. The debugger may well have
other information available that makes that inference stronger.
(Conceivably a compiler could generate code to test the value of ptr
against 0x00000000 before attempting to add the offset to it; that could
catch the error slightly sooner and more directly, but at a considerable
performance cost.)
I believe you've been implying that this means that 0x0000000c is
a null pointer. It isn't. Seeing Philip's remark, quoted above,
it's a little clearer why you might have thought so.
[snip]
A pointer with the value 0x0000000c is not a null pointer, nor does it
point to any object. It is, I believe, a trap representation. In
certain contexts, the existence of such a pointer may imply that there's
been an attempt to dereference a null pointer; the null pointer itself
(in this particular implementation) has the representation 0x00000000.
Finally, a correction to something I may or may not have implied
earlier. Creating such a pointer, by evaluating `(void*)0x0000000c`,
does not itself have undefined behavior; 6.3.2.3p5 says that the
conversion may yield a trap representation, not that the conversion
itself has undefined behavior. Any attempt to *use* such a pointer
value does have undefined behavior.
0x0000000c;
/* obviously ok, no UB */
(void*)0x0000000c;
/* Creates a trap representation, then discards it; no UB */
p = (void*)0x0000000c;
/* Attempts to access a trap representation, UB */
if ((void*)0x0000000c) == NULL) ...
/* UB */
It's very likely that the third statement will quietly store the
expected value in `p`, and that the last will evaluate the condition as
false; these are entirely consistent with the behavior being undefined.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-21 19:45 -0800 |
| Message-ID | <kfnehhd7uet.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30485 |
Keith Thompson <kst-u@mib.org> writes:
>> [snip]
>>
> Finally, a correction to something I may or may not have implied
> earlier. Creating such a pointer, by evaluating `(void*)0x0000000c`,
> does not itself have undefined behavior; 6.3.2.3p5 says that the
> conversion may yield a trap representation, not that the conversion
> itself has undefined behavior. Any attempt to *use* such a pointer
> value does have undefined behavior. [snip examples]
Strictly speaking the result of a conversion cannot be a trap
representation, because the result of a conversion is a value
and a trap representation is not a value but an object
representation. The Standard is being careless in how it
uses the term here.
Despite that, the intention seems clear, namely, that converting
any value where the result cannot be used as a pointer (for
example, for comparison to NULL) is undefined behavior,
regardless of whether the resulting value is used or discarded
(ie, converted to (void)). There isn't any point in being
allowed to produce a value but then not be able to do anything
with it, or even just store it. Furthermore this is how we
expect actual hardware would work -- it is trying to construct
a bogus address value that is likely to cause a trap, not doing
a store operation to put the bogus result in memory.
A quote from the C99 Rationale document might be illuminating
here:
Since pointers and integers are now considered incommensurate,
the only integer value that can be safely converted to a
pointer is a constant expression with the value 0.
Considering the context in which it was made, this statement
seems exactly on point.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-22 00:18 -0500 |
| Message-ID | <kdl7ek$45s$1@dont-email.me> |
| In reply to | #30485 |
On 1/21/2013 18:50, Keith Thompson wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>> On 1/21/2013 15:17, Keith Thompson wrote:
>>> Shao Miller <sha0.miller@gmail.com> writes:
>>>> - VA32: Any pointer type with a representation that is 32 bits and
>>>> which has no trap representations.
>>>
>>> What makes you think that 32-bit pointers on MS Windows have no
>>> trap representations? `(void*)0x0000000C` almost certainly is a
>>> trap representation for the implementation in question. (I'm using
>>> the phrase "trap representation" as the C standard uses it; I lack
>>> interest in any other meanings *unless* some documentation uses
>>> that exact phrase with a different meaning.)
>>
>> Well I didn't quite say that. I was referring to a particular subset of
>> 32-bit pointers. I would certainly consider the representation
>> 0x00000001 to be a trap representation for an 'int *' in 32-bit Windows.
>
> Yes, you did quite say that. You said the pointer type "has no trap
> representations".
>
I did _not_ say "that 32-bit pointers on MS Windows have no trap
representations". I said that a "VA32", an "unsafe pointer" and a "lull
pointer" do not have trap representations. Yes, I meant to imply that
there was some relevance to Windows. The relationship I would suggest
between a VA32 and Windows is described immediately below.
>> For VA32 (which would correspond to 'void *', 'char *', etc.), the
>> reason I would think that is that I've over a decade of use, I guess. I
>> could be wrong! But here's a starting-point, perhaps:
>>
>> http://msdn.microsoft.com/en-us/library/k26sa92e.aspx
>
> That looks a lot like the C Standard's requirements for pointer
> conversions, with some extra information about how Microsoft's compiler
> performs such conversions. Unlike the standard, it doesn't mention trap
> representations.
>
There is a good reason for this: It conforms to C90. There were no trap
representations in C90. Fortunately, developing for Windows doesn't
require any. What we do have are what's been available since the
dinosaurs roamed the data-centre: Bit patterns that carry useful
debugging information.
>> Wait, are you saying that any pointer that does not match one of {null
>> pointer, points to an object} must necessarily be a trap representation?
>
> I believe so, yes.
>
> Given a pointer value that is neither a null pointer nor a pointer to an
> object [or function], what criteria would cause you to claim that it's *not* a trap
> representation?
>
I think it has to work the other way around. I think the implementation
has to define it as a trap representation. I don't think we can infer
this property from anything that any Standard says. This could be where
our agreement diverges.
>> I haven't intentionally backed away from any claims. I wish I knew what
>> claims you might be referring to.
>>
> /* Let struct foo have a member m at offset 12 (0xc) */
> struct foo *ptr = NULL;
> do_something_with(foo->m);
>
> The evaluation of `foo->m` has undefined behavior because the value of
> `foo` is a null pointer.
Agreed.
> It's likely that the generated code will take
> the value stored in `foo` (0x00000000), add the offset 12 to it
> (yielding 0x0000000c), and then attempt to dereference the resulting
> pointer value. If the program is being executed under the debugger,
> this is likely to cause a trap. The debugger sees an attempt to
> dereference address 0x0000000c and, quite reasonably, infers that it was
> probably the result of accessing a member of a structure or class, at an
> offset of 12 bytes, via a null pointer. The debugger may well have
> other information available that makes that inference stronger.
>
> (Conceivably a compiler could generate code to test the value of ptr
> against 0x00000000 before attempting to add the offset to it; that could
> catch the error slightly sooner and more directly, but at a considerable
> performance cost.)
>
> I believe you've been implying that this means that 0x0000000c is
> a null pointer. It isn't. Seeing Philip's remark, quoted above,
> it's a little clearer why you might have thought so.
>
I did not mean to imply that. Glen Herrmannsfeldt suggested a scenario
where that could be true, but I responded by saying that his case was
"along the lines that might be" the case I was talking about, which is
exactly true: The Microsoft debugger distinguishes between an invalid
pointer and an invalid pointer in the "null class". This implies that
the bits are significant and Glen's masking comes into play. It does
_not_ imply that that I'm saying 0x0000000C is a null pointer. If it
was confusing before, it should have been clear once I answered you
about it comparing as unequal with a null pointer. Sorry about the
confusion.
> [snip]
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-22 08:01 -0800 |
| Message-ID | <ln8v7l5hqr.fsf@nuthaus.mib.org> |
| In reply to | #30494 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/21/2013 18:50, Keith Thompson wrote:
[...]
>> I believe you've been implying that this means that 0x0000000c is
>> a null pointer. It isn't. Seeing Philip's remark, quoted above,
>> it's a little clearer why you might have thought so.
>
> I did not mean to imply that. Glen Herrmannsfeldt suggested a scenario
> where that could be true, but I responded by saying that his case was
> "along the lines that might be" the case I was talking about, which is
> exactly true: The Microsoft debugger distinguishes between an invalid
> pointer and an invalid pointer in the "null class". This implies that
> the bits are significant and Glen's masking comes into play. It does
> _not_ imply that that I'm saying 0x0000000C is a null pointer. If it
> was confusing before, it should have been clear once I answered you
> about it comparing as unequal with a null pointer. Sorry about the
> confusion.
You're inferring that the debugger message "NULL_CLASS_PTR_DEREFERENCE"
refers to pointers in the "null class". I don't think that's what it
means.
Microsoft's development environment places a greater emphasis on C++
than on C. An attempted dereference of address 0x0000000C is likely
to result from an attempt to dereference a pointer to a class type
(in C++, structs are classes), and the debugger may have more
information that strengthens this inference.
class foo {
public:
char x[12];
int y;
};
foo* ptr = 0;
int kaboom = ptr->y;
(I just tried running a C++ program with the above code under MS Visual
C++ 2010 Express, and didn't get that message; instead, I got "Unhandled
exception at 0x009013a8 in null_class_ptr.exe: 0xC0000005: Access
violation reading location 0x0000000c.".)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-18 23:02 -0500 |
| Message-ID | <kdd5sn$ens$1@dont-email.me> |
| In reply to | #30334 |
On 1/18/2013 20:38, Keith Thompson wrote: > Shao Miller <sha0.miller@gmail.com> writes: >> On 1/18/2013 11:41, Keith Thompson wrote: >>> Shao Miller <sha0.miller@gmail.com> writes: > [...] >>>> I think all-bits-zero is one null pointer value representation, but I >>>> was talking about "trap representations" in practice (as opposed to a >>>> discussion of those that depend on padding bits). In Windows NT >>>> kernel-land, more often than not I see that when a null pointer is >>>> trapped, it's actually _not_ all-bits-zero; differing in the LSB. The >>>> debugger still calls it a null pointer. >>> >>> A null pointer is not a trap representation; it's a perfectly valid >>> pointer value (that can't legally be dereferenced). >>> >> >> Agreed. And that's kind of what I was getting at... That this >> representation is: >> >> 1. A valid null pointer representation (behaves as a null pointer in C >> code; no undefined behaviour from using this pointer value unless >> dereferencing) >> >> 2. Very consistently _not_ all-bits-zero, suggesting a practical use for >> a debugger to trap (as opposed to a same-sized integer/object with >> all-zeroes) > > When you say it "behaves as a null pointer in C code", what exactly do > you mean by that? > > Does it compare equal to NULL? If not, then it *doesn't* behave as a > null pointer in C code. > Yeah, come to think of it, you're right: I guess it wouldn't've behaved _exactly_ the same. >>> What exactly do you mean when you say "The debugger still calls it a >>> null pointer"? Does the debugger actually use the phrase "null pointer" >>> to refer to a pointer value that compares unequal to NULL? >> >> It absolutely does. (I see it more often than I'd like, some days. ;) ) >> I suspect that it's an instance of trap representations in practice, >> as opposed to "trap representations" in C theory. > > A lot of technical terms have specific meanings in C that may not apply > in other contexts. If a debugger refers to something other than a C > null pointer as a "null pointer", then (a) it's a pity that a tool that > deals with C source code uses a term in a manner that's inconsistent > with the C meaning of the term, but (b) it doesn't have much direct > bearing on C (i.e., on anything relevant to this newsgroup). > Well I have to offer partial disagreement with (a). I think that the practical usage of some terms finds Standard C in a good position to consider adjusting its definitions. :) WinDbg can handle C++ and assembly too, so the terms it uses seem more likely to be "as practiced" rather than "as preached". > Can you point to some documentation that discusses this use of the term > "null pointer"? > On 1/16/2013 20:57, Shao Miller wrote: > I thought null pointers having 0x0C as the least-significant byte was "a thing," too, but now I can't remember having seen that documented anywhere. Sorry for the confusion. I was talking about a recollection, as shown in the sentence, above. What I'm recalling is associated with "NULL_CLASS_PTR_DEREFERENCE", but please see the sentence above, regarding documentation. I thought I remembered the LSB 0x0C pattern was used as "trap representation" for "null pointers", but where neither of these terms are quite what they are in C. If I ever come across such documentation, I'll share it. Maybe Geoff has a clue? -- - Shao Miller -- "Thank you for the kind words; those are the kind of words I like to hear. Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2013-01-19 01:28 -0800 |
| Message-ID | <MPG.2b64071042b5d6249896e7@news.eternal-september.org> |
| In reply to | #30334 |
Keith Thompson wrote:
> Shao Miller writes:
> > Keith Thompson wrote:
> >> Shao Miller writes:
> >>> I think all-bits-zero is one null pointer value representation,
> >>> but I was talking about "trap representations" in practice (as
> >>> opposed to a discussion of those that depend on padding bits).
> >>> In Windows NT kernel-land, more often than not I see that when
> >>> a null pointer is trapped, it's actually _not_ all-bits-zero;
> >>> differing in the LSB. The debugger still calls it a null pointer.
> >>
> >> A null pointer is not a trap representation; it's a perfectly valid
> >> pointer value (that can't legally be dereferenced).
> >
> > Agreed. And that's kind of what I was getting at... That this
> > representation is:
> >
> > 1. A valid null pointer representation (behaves as a null pointer in C
> > code; no undefined behaviour from using this pointer value unless
> > dereferencing)
> >
> > 2. Very consistently _not_ all-bits-zero, suggesting a practical use for
> > a debugger to trap (as opposed to a same-sized integer/object with
> > all-zeroes)
>
> When you say it "behaves as a null pointer in C code", what exactly do
> you mean by that?
>
> Does it compare equal to NULL? If not, then it *doesn't* behave as a
> null pointer in C code.
I would guess that he's seeing something like the following:
struct {
int a, b, c, d;
} *p = NULL;
p->d = 0;
This traps in the debugger, and the debugger reports a "null pointer
dereference" at address 0x0000000c.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-19 12:08 -0500 |
| Message-ID | <kdejtt$k0c$1@dont-email.me> |
| In reply to | #30342 |
On 1/19/2013 04:28, Philip Lantz wrote:
> Keith Thompson wrote:
>> Shao Miller writes:
>>> Keith Thompson wrote:
>>>> Shao Miller writes:
>>>>> I think all-bits-zero is one null pointer value representation,
>>>>> but I was talking about "trap representations" in practice (as
>>>>> opposed to a discussion of those that depend on padding bits).
>>>>> In Windows NT kernel-land, more often than not I see that when
>>>>> a null pointer is trapped, it's actually _not_ all-bits-zero;
>>>>> differing in the LSB. The debugger still calls it a null pointer.
>>>>
>>>> A null pointer is not a trap representation; it's a perfectly valid
>>>> pointer value (that can't legally be dereferenced).
>>>
>>> Agreed. And that's kind of what I was getting at... That this
>>> representation is:
>>>
>>> 1. A valid null pointer representation (behaves as a null pointer in C
>>> code; no undefined behaviour from using this pointer value unless
>>> dereferencing)
>>>
>>> 2. Very consistently _not_ all-bits-zero, suggesting a practical use for
>>> a debugger to trap (as opposed to a same-sized integer/object with
>>> all-zeroes)
>>
>> When you say it "behaves as a null pointer in C code", what exactly do
>> you mean by that?
>>
>> Does it compare equal to NULL? If not, then it *doesn't* behave as a
>> null pointer in C code.
>
> I would guess that he's seeing something like the following:
>
> struct {
> int a, b, c, d;
> } *p = NULL;
>
> p->d = 0;
>
> This traps in the debugger, and the debugger reports a "null pointer
> dereference" at address 0x0000000c.
>
Indeed! Or, perhaps more commonly:
typedef struct { UINT32 A, B, C, D; } FOO, * PFOO;
PUINT32 GetFooD(PFOO foo) {
return &foo->D;
}
(I don't particularly like pointer typedefs, but pretend they're
Microsoft's.)
Then the caller dereferences the returned pointer, or passes it around
until some other function does. That is, I find that it's not usually
quite as obvious as in your example, and sometimes due to opacity or
abstraction.
(And thanks for the set-up for the function name; I'm hungry. :) )
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Geoff <geoff@invalid.invalid> |
|---|---|
| Date | 2013-01-21 09:27 -0800 |
| Message-ID | <7buqf8hvngf4mcetcph7d88nq8h0depsvs@4ax.com> |
| In reply to | #30274 |
On Thu, 17 Jan 2013 16:47:53 -0500, Shao Miller <sha0.miller@gmail.com> wrote: >On 1/17/2013 10:55, Keith Thompson wrote: >> Shao Miller <sha0.miller@gmail.com> writes: >>> On 1/16/2013 20:32, Geoff wrote: >> [...] >>>> Microsoft documents their compiler trap values: >>>> Value Name Description >>>> ------ -------- ------------------------- >>>> 0xCD Clean Memory Allocated memory via malloc or new but never >>>> written by the application. >>>> >> [snip] >>>> 0xFEEEFEEE OS fill heap memory, which was marked for usage, >>>> but wasn't allocated by HeapAlloc() or LocalAlloc(). >>>> Or that memory just has been freed by HeapFree(). >>> >>> Wonderful, wonderful summary! I thought null pointers having 0x0C as >>> the least-significant byte was "a thing," too, but now I can't remember >>> having seen that documented anywhere. >> >> I'm fairly sure Microsoft uses all-bits-zero for null pointers. Most >> implementations do the same thing, though of course the standard doesn't >> require it. >> > >I think all-bits-zero is one null pointer value representation, but I >was talking about "trap representations" in practice (as opposed to a >discussion of those that depend on padding bits). In Windows NT >kernel-land, more often than not I see that when a null pointer is >trapped, it's actually _not_ all-bits-zero; differing in the LSB. The >debugger still calls it a null pointer. > I'm not sure that when Windows traps in the manner you speak of that it's a NULL pointer exception. It's most likely an x86 protected mode exception being reported due to dereference of a pointer outside the process allocated virtual address space. This mechanism is outside the purview of the C standard. Can you post a simple code example that exhibits the behavior you describe?
[toc] | [prev] | [next] | [standalone]
Page 5 of 6 — ← Prev page 1 2 3 4 [5] 6 Next page →
Back to top | Article view | comp.lang.c
csiph-web