Re: printf("%p\n", (void *)0);
From: James Kuyper (kuyper_at_saicmodis.com)
Date: 03/07/05
- Next message: Marc Olzheim: "Re: Signal 11 error (core)"
- Previous message: abhrajit_at_hotmail.com: "Balanced binary tree with fixed leaf nodes"
- In reply to: frob: "Re: printf("%p\n", (void *)0);"
- Next in thread: Keith Thompson: "Re: printf("%p\n", (void *)0);"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 07 Mar 2005 16:47:21 -0500
frob wrote:
> I was unclear in my previous post. I will attempt to clear it up.
>
> When I spoke of a machine with even boundaries for char types, I was
> referring to the actual executable code after the translation from C has
> occurred. I was not referring to the C program source. I apologize for
> being unclear on that point. I was not trying to state or imply that a
> char* +1 would always be even in the C language. I was referring entirly to
> the translated code for the execution environment.
That sounds reasonable in itself. However, the above comments (assuming
that you and I are both understanding them the same way) render your
previous argument about an NPC being 'odd' meaningless.
On a machine where addresses are required to point to word boundaries,
with words being two bytes long (a not uncommon architecture) then a
char* pointer will have to be represented by the combination of a
machine address plus some mechanism for determining which byte of the
word the character is in. On some platforms, a high-order bit within the
machine address is used by the C implementation for this purpose; this
requires that the chosen bit is not used by the machine itself. When
that approach is not feasible, it generally means that if a type T is
word aligned, then sizeof(char*) > sizeof(T*). A pointer to void is
required to have the same representation as 'char *', and will therefore
be just as easily capable of representing "odd" addresses as a 'char*'
pointer itself.
...
> Nowhere in the standard can I find that (void*)0 has or can be converted to
> the "same representation and alignment requirements" as specified for the
> purposes of a pointer to void. This is implied in several cases, but never
> explicitly stated (to my knowledge). The 6.3.2.4p4 statement, "Conversion
> of a null pointer to another pointer type yields a null pointer of that
> type." This is the closest I can find, but it does not meet the exact
> wording given in 6.2.6p26, respecting the "same representation and alignment
> requirements."
Keep in mind that objects contain represent ions of values; the value
'1' doesn't have to have a specific representation as far as C is
concerned, until it's actually stored in an object. In actual practice,
there are real machines where registers use different representations
than RAM for certain types, in which case loading the value from RAM
into a register requires a change of representation.
When it's permitted for a type to have multiple representations for a
given value (as is the case for null pointer values), there's no
guarantee that storing the same value in different objects, or in the
same object at different times, will result in the same representation
being created. Therefore, it's meaningless to ask what "the"
representation of (void*)0 is. However, an implementation is required to
create a valid representation in any 'void*' object that (void*)0 is
stored in.
You're not supposed to conclude that it qualifies as a pointer to void
because it meets those representation and alignment requirements when
stored in an object; it hasn't been stored in an object yet (and
depending upon context, it might never be), so there's no way to tell.
What you can infer is that it will meet those requirements if it gets
stored in an object because it's required (as a result of the 'void*'
cast) to be a null pointer value of type pointer to void. Since the
conversion is guaranteed to succeed, and the result of that conversion
is guaranteed to be usable in various contexts, it must also be
considered valid, at least in a limited sense. Therefore, when it gets
stored in an object the implementation is required to select a valid
representation for the value, one that matches one of the valid
representations for a 'char*' pointer with the same value (i.e., a null
pointer value).
> Yes, it is a very small detail, and yes, it probably should be interpreted
> as meeting those requirements. However, if we are going to be splitting
> hairs over the standard, I will refer to the definition of 'implies' in
> logic, which fails in this exact case.
This isn't splitting hairs; it's trying to perform the inference exactly
backwards, which is doomed to failure. (void*)0 has type 'pointer to
void' for precisely the same reason that (long)3 has type 'long int'. If
you try to find the part of the standard which describes the
representation of (long)3, to determine whether or not it meets the
requirements of 6.2.6.2, you'll have just as much trouble as you had
looking for text describing the representation and alignment of
(void*)0, and for precisely the same reasons.
It's up to the implementation to ensure that the representation for
(void*)0 meets the requirements of 6.2.5p26 for pointers to void when it
gets stored in a void* object. That's for the same reasons that it's the
responsibility of the implementation to ensure that (long)3 meets the
requirements of section 6.2.6.2 for the representation of integer types
when it gets stored in a 'long' object.
- Next message: Marc Olzheim: "Re: Signal 11 error (core)"
- Previous message: abhrajit_at_hotmail.com: "Balanced binary tree with fixed leaf nodes"
- In reply to: frob: "Re: printf("%p\n", (void *)0);"
- Next in thread: Keith Thompson: "Re: printf("%p\n", (void *)0);"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|