Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > [union] Pointers to inherited structs are valid ?

Reply
Thread Tools

[union] Pointers to inherited structs are valid ?

 
 
Tim Rentsch
Guest
Posts: n/a
 
      01-21-2013
Philip Lantz <(E-Mail Removed)> writes:

>> [snip]

>
> The undefined behavior occurred when &ptr->bar was executed (with ptr
> equal to NULL). [snip]


Actually just slightly before -- when ptr is a null pointer,
evaluating ptr->bar is already undefined behavior.
 
Reply With Quote
 
 
 
 
Geoff
Guest
Posts: n/a
 
      01-21-2013
On Thu, 17 Jan 2013 16:47:53 -0500, Shao Miller <(E-Mail Removed)> wrote:

>On 1/17/2013 10:55, Keith Thompson wrote:
>> Shao Miller <(E-Mail Removed)> 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?
 
Reply With Quote
 
 
 
 
Shao Miller
Guest
Posts: n/a
 
      01-21-2013
On 1/21/2013 01:02, Keith Thompson wrote:
> Shao Miller <(E-Mail Removed)> 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? }

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      01-21-2013
On 1/21/2013 12:27, Geoff wrote:
> On Thu, 17 Jan 2013 16:47:53 -0500, Shao Miller <(E-Mail Removed)> wrote:
>
>> On 1/17/2013 10:55, Keith Thompson wrote:
>>> Shao Miller <(E-Mail Removed)> 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?
>


I thought it was obvious that the mechanism was via page fault and that
the bits of the attempted address were examined in order to determine
some useful information about the nature of a recent problem. All I was
wondering was if 0x0000000C had a particular meaning for debugging, like
your values above.

Mr. Philip Lantz suggested that the origin of such a thing is from a
pointer resulting from a computation involving a null pointer. (See
below.) Having read his post, this seems pretty obvious to be the
likely case, to me.

On 1/19/2013 04:28, Philip Lantz wrote:
> 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.


--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      01-21-2013
On 1/21/2013 11:31, Ben Bacarisse wrote:
> Shao Miller <(E-Mail Removed)> writes:
>>
>> Not explicitly, no. I thought it would be obvious that it was the
>> context of a Windows debugger notifying the programmer, since Geoff
>> had just discussed that.

>
> I don't recall Geoff saying that anything was unexpected. That's your
> phrase that you admit you have not defined. I can't fathom what you
> think is unexpected behaviour or what point that would made. Should I
> be able to work it out?
>


No, I'm explaining the nature of my mistake. "I thought it would be
obvious." <- Wrong.

> Geoff's post looks simple and correct: the standard permits trap
> representations that produce undefined behaviour so an implementation is
> permitted to use special values to trigger interesting effects (either
> in a debugger or else where).
>


I agree that his post does look that way and that C does allow for that.
There's a subtle bit here, though: If we're discussing a program, once
that program invokes undefined behaviour, anything goes. However, if
I'm not mistaken, with Windows NT, if you have a pointer value which
does not point to an object, the program will continue to operate as per
the C semantics until such a time (if ever) as that pointer might be
used for indirect access.

So it is imprecise to say that such a value has a trap representation,
because the behaviour is still well-defined. Otherwise, the last
sentence of N1570's 6.5.3.2p4 is redundant:

"If an invalid value has been assigned to the pointer, the behavior
of the unary * operator is undefined.102)"

But anyway, a pointer value pointing to no object can still be "trapped"
by Windows during indirection and can still provide useful information
to a Windows debugger. It just does not precisely match C's trap
representation, for behavioural differences.

>
> No I read in context and try to respond in context as well. I don't
> think I missed the context.
>


Well then that's my mistake.

>> In that quote, I thought it was obvious that this
>> was in the context of using a Microsoft debugger, where the behaviour
>> would agree with the semantics of an "unspecified value"; not warning
>> the programmer during a read of the value (which it _could_).

>
> It could be an unspecified value (you are explicitly using C terms here)
> if it is a valid pointer value. It may well be. Is it? It may equally
> well not be. It could be either a trap representation or an unspecified
> value but you seem to suggest that it is one not the other. You seem to
> suggest that one possibility is more likely than the other for reasons
> that are spurious. The best evidence that it might not be a trap
> representation is that it's a valid pointer, but you give no evidence for
> that -- quite the contrary in fact.
>


I'd say that it is not a trap representation.

Take Windows NT's 'IRP' structure. It has a sub-member called
'Tail.Overlay.DriverContext', which is an array of 4 'void *'. This is
one of _very_few_ places where a driver can associate information with
an IRP, and is extremely valuable for that reason.

The implementation defines the results of casting an appropriately-sized
integer value to a 'void *', so such an integer can be "passed" via this
mechanism. We _certainly_ would not wish to believe that this results
in undefined behaviour, so we certainly would not wish to believe that
such a result is a trap representation.

>>
>> B: "Here are Microsoft's documented [non-C] trap values..."

>
> If this was Geoff, he correctly called then "trap representation"
> (rather than values) and he referred to "they" meaning the C committee.
> He was talking at C trap representations not "[non-C] trap values".
>


This was in regards to the lower part of his post where he specifically
says "Microsoft documents their compiler trap values".

>> Me: "Nice summary! Say, isn't there another one, 0x0000000C, as a
>> [non-C] trap for [non-C] null pointers? I don't remember..."
>>
>> C: "Oh no, that wouldn't be a [C] null pointer."
>>
>> Me: "Yes, well I was talking about B's [non-C] trap values. I see a
>> Microsoft debugger catch these things and call them [non-C] null
>> pointers."

>
> I think you missed Geoff's point.
>


I doubt it.

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-21-2013
Shao Miller <(E-Mail Removed)> writes:
> On 1/21/2013 01:02, Keith Thompson wrote:
>> Shao Miller <(E-Mail Removed)> 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? }


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) http://www.velocityreviews.com/forums/(E-Mail Removed) <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"
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      01-21-2013
Keith Thompson <(E-Mail Removed)> 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
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      01-21-2013
Shao Miller <(E-Mail Removed)> wrote:

(snip, someone wrote)
>> Can you post a simple code example that exhibits the behavior you describe?


> I thought it was obvious that the mechanism was via page fault and that
> the bits of the attempted address were examined in order to determine
> some useful information about the nature of a recent problem. All I was
> wondering was if 0x0000000C had a particular meaning for debugging, like
> your values above.


If anyone ever used large model (48 bit pointers, with a 16 bit segment
selector and 32 bit offset) on 80386 and later processors, there are
many interesting things one could do.

> Mr. Philip Lantz suggested that the origin of such a thing is from a
> pointer resulting from a computation involving a null pointer. (See
> below.) Having read his post, this seems pretty obvious to be the
> likely case, to me.


I have no idea how MS does the page tables, though.

If the whole page with high bits zero is invalid, one might be able
to do some interesting things.

-- glen
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-21-2013
Shao Miller <(E-Mail Removed)> writes:

> On 1/21/2013 11:31, Ben Bacarisse wrote:

<snip>
>> Geoff's post looks simple and correct: the standard permits trap
>> representations that produce undefined behaviour so an implementation is
>> permitted to use special values to trigger interesting effects (either
>> in a debugger or else where).

>
> I agree that his post does look that way and that C does allow for
> that. There's a subtle bit here, though: If we're discussing a
> program, once that program invokes undefined behaviour, anything goes.
> However, if I'm not mistaken, with Windows NT, if you have a pointer
> value which does not point to an object, the program will continue to
> operate as per the C semantics until such a time (if ever) as that
> pointer might be used for indirect access.


Of course. The "C semantics" are exactly as you describe: "anything
goes". If such a program caused the machine to halt, that, too, would
be operating as per "C semantics".

> So it is imprecise to say that such a value has a trap representation,
> because the behaviour is still well-defined. Otherwise, the last
> sentence of N1570's 6.5.3.2p4 is redundant:
>
> "If an invalid value has been assigned to the pointer, the behavior
> of the unary * operator is undefined.102)"


Presumably you read the footnote so you must be aware of all the invalid
values that this clause covers.

A particular bit-pattern (0xC in this case, I think) can either
represent a valid value (for the pointer type in question), an invalid
value, or it can be a trap representation. These three possibilities
are, at a particular time in the program's execution, mutually
exclusive. The middle category, invalid pointer values, needs 6.5.3.2
p4.

> But anyway, a pointer value pointing to no object can still be
> "trapped" by Windows during indirection and can still provide useful
> information to a Windows debugger. It just does not precisely match
> C's trap representation, for behavioural differences.


What's the difference? The behaviour you describe here matches what you
can expect from what C calls a trap representation.

>> No I read in context and try to respond in context as well. I don't
>> think I missed the context.
>>

>
> Well then that's my mistake.
>
>>> In that quote, I thought it was obvious that this
>>> was in the context of using a Microsoft debugger, where the behaviour
>>> would agree with the semantics of an "unspecified value"; not warning
>>> the programmer during a read of the value (which it _could_).

>>
>> It could be an unspecified value (you are explicitly using C terms here)
>> if it is a valid pointer value. It may well be. Is it? It may equally
>> well not be. It could be either a trap representation or an unspecified
>> value but you seem to suggest that it is one not the other. You seem to
>> suggest that one possibility is more likely than the other for reasons
>> that are spurious. The best evidence that it might not be a trap
>> representation is that it's a valid pointer, but you give no evidence for
>> that -- quite the contrary in fact.

>
> I'd say that it is not a trap representation.


But you don't say why. The "it" above presumably refers to what we've
been talking about -- that 0xC bit-pattern. Your only evidence that
it's not a trap representation seems to be that nothing "odd" happens
until you dereference it. That's entirely consistent with it being a
trap representation.

> Take Windows NT's 'IRP' structure. It has a sub-member called
> Tail.Overlay.DriverContext', which is an array of 4 'void *'. This is
> one of _very_few_ places where a driver can associate information with
> an IRP, and is extremely valuable for that reason.
>
> The implementation defines the results of casting an
> appropriately-sized integer value to a 'void *', so such an integer
> can be "passed" via this mechanism. We _certainly_ would not wish to
> believe that this results in undefined behaviour, so we certainly
> would not wish to believe that such a result is a trap representation.


Are you saying that something can't be a trap representation because
something other than C defines what happens when it's used? That's
exactly why, in part, C leaves so many things undefined (the behaviour
of trap representations being one such thing) so that implementations
are free to do useful things in such situations.

<snip>
--
Ben.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-21-2013
Shao Miller <(E-Mail Removed)> writes:
[...]
> I agree that his post does look that way and that C does allow for
> that. There's a subtle bit here, though: If we're discussing a
> program, once that program invokes undefined behaviour, anything goes.
> However, if I'm not mistaken, with Windows NT, if you have a pointer
> value which does not point to an object, the program will continue to
> operate as per the C semantics until such a time (if ever) as that
> pointer might be used for indirect access.


I (mostly) agree with that.

> So it is imprecise to say that such a value has a trap representation,
> because the behaviour is still well-defined. Otherwise, the last
> sentence of N1570's 6.5.3.2p4 is redundant:
>
> "If an invalid value has been assigned to the pointer, the behavior
> of the unary * operator is undefined.102)"


No. Accessing an object with a trap representation has undefined
behavior. What that means is that the behavior is not defined *by the C
standard*; see N1370 3.4.3, the definion of the phrase "undefined
behavior". Another entity can certainly define behavior for such
accesses.

For example, (void*)0x0000000C is very likely a trap representation
under Windows NT. The behavior of applying unary "*" to that value is
undefined, in the sense that the C standard does not define its
behavior. Windows NT can define the behavior if it likes; that doesn't
cause it to cease being a trap representation.

> But anyway, a pointer value pointing to no object can still be
> "trapped" by Windows during indirection and can still provide useful
> information to a Windows debugger. It just does not precisely match
> C's trap representation, for behavioural differences.


Yes, it does.

[...]

> Take Windows NT's 'IRP' structure. It has a sub-member called
> Tail.Overlay.DriverContext', which is an array of 4 'void *'. This is
> one of _very_few_ places where a driver can associate information with
> an IRP, and is extremely valuable for that reason.
>
> The implementation defines the results of casting an
> appropriately-sized integer value to a 'void *', so such an integer
> can be "passed" via this mechanism. We _certainly_ would not wish to
> believe that this results in undefined behaviour, so we certainly
> would not wish to believe that such a result is a trap representation.


I'm afraid that what you wish is irrelevant. It has undefined behavior.
A program that depends on the behavior of some construct whose behavior
is not defined by the C standard is not portable. There's nothing wrong
with that; sometimes you *need* to write non-portable code, code that
depends on guarantees made by a given environment but not by the
language standard.

Don't forget that "undefined behavior" does not* mean "this will crash".
It means exactly what the C standard says it means in 3.4.3: "behavior,
upon use of a nonportable or erroneous program construct or of erroneous
data, for which this International Standard imposes no requirements".

A given construct causing Microsoft's debugger to consistently display a
"NULL_CLASS_PTR_DEREFERENCE" message is perfectly consistent with that
construct having undefined behavior as defined by the C standard. If
you don't understand that, you don't understand undefined behavior.

>>> B: "Here are Microsoft's documented [non-C] trap values..."

>>
>> If this was Geoff, he correctly called then "trap representation"
>> (rather than values) and he referred to "they" meaning the C committee.
>> He was talking at C trap representations not "[non-C] trap values".
>>

>
> This was in regards to the lower part of his post where he
> specifically says "Microsoft documents their compiler trap values".


Here's Geoff's article:

https://groups.google.com/group/comp...ain&noredirect

The "compiler trap values" that Microsoft documents are not the same
thing as C "trap representations" (that's probably why they have
a *different name*, and Geoff merely said that they're *analagous"
to C trap representations. For example, "Clean Memory" is filled
with 0xCD bytes, which can easily represent a valid value for some
type (certainly for unsigned char).

>>> Me: "Nice summary! Say, isn't there another one, 0x0000000C, as a
>>> [non-C] trap for [non-C] null pointers? I don't remember..."
>>>
>>> C: "Oh no, that wouldn't be a [C] null pointer."
>>>
>>> Me: "Yes, well I was talking about B's [non-C] trap values. I see a
>>> Microsoft debugger catch these things and call them [non-C] null
>>> pointers."

>>
>> I think you missed Geoff's point.

>
> I doubt it.


If you think Geoff was using the phrase "null pointer" or "trap
representation" to refer to anything other than a null pointer
or trap representation as defined by the C standard, then yes,
you missed Geoff's point.

"I see a Microsoft debugger catch these things and call them [non-C]
null pointers." -- I don't believe you have seen that.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <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"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
'Class.inherited' v. 'inherited' syntax inside Class 7stud -- Ruby 11 11-09-2007 06:45 PM
Packed structs vs. unpacked structs: what's the difference? Daniel Rudy C Programming 15 04-10-2006 08:10 AM
Array of structs instead of an array with pointers to structs? Paminu C Programming 5 10-11-2005 07:18 PM
const structs in other structs Chris Hauxwell C Programming 6 04-27-2004 07:03 PM
structs with fields that are structs Patricia Van Hise C Programming 5 04-05-2004 01:37 AM



Advertisments