Keith Thompson said:
But 0 is a null pointer constant, which can legally be used to
initialize a pointer variable (it's implicitly converted to a null
pointer value). See section 5 of the comp.lang.c FAQ,
<
http://www.c-faq.com/>, for more information on null pointers.
And, it may or may not actually point to physical address zero due to
segmentation or it may be non-zero NULL if an object or function uses that
address. What does this have to do with the OP's problem of not casting
addresses or, perhaps, declaring his variables improperly? (nothing) You act
as if I wrote the code instead of correcting it in a manner which would I
believe will benefit the OP.
This initializes p to the value 3 converted to int*. It's very
unlikely that this will be meaningful. (If you happen to know that
there's some int object at address 3 you can do this.)
Whether it is useful or not is up to him. I believe to be more inline with
what the OP was _trying_ to do than the other posts.
The point was to teach him about casting addresses, and being aware of type
differences. But, once again, you seem lost... Did you understand that
this is a beginner in C? Why do you intend to confuse him with advanced
topics such as how NULL is implemented and whether it corresponds to
physical address and what value it may be? You ripped me to shreds over
teaching a new programmer the truth about the advanced topic of arrays being
pointers... Now you turn around and do the same... Pick one side and stay
there.
This converts x from int* to unsigned int. The result of such a
conversion is implementation-defined, and may not be meaningful. An
unsigned int may not even be big enough to hold the value of a
pointer.
If you want to print the value of a pointer, cast it to void* and use
"%p".
I simply corrected the OP's code keeping his preferred conversion. If I had
written it, I'd have used '%08lx' and '(unsigned long)' since it works where
I need it.
First, %p also prints in an "implementation-defined" manner which may be
just as useless. (ISO C 7.19.6.1)
Second, all pointer conversions are capable of producing UB. (ISO C 6.3.2.3
sub 7)
Third, the conversion from an 'int *' to a 'void *' is also
"implementation-defined, and may not be meaningful." It is only required
that conversion of a type such as an 'int *' to 'void *' and _back_ to the
original type, 'int *', from the intermediate 'void *' be lossless. (ISO C
6.3.2.3) The resulting 'void *' is required to be the functionally the same
as a 'char *' (ISO C 6.2.5 s 26). But, only explicit conversions to 'char
*', i.e., not 'void *', are required to be "meaningful" by pointing to the
lowest byte of the object. (ISO C 6.3.2.3 sub 7) Other than being required
to be functionally equivalent to a valid pointer to char, I don't see
anything requiring the intermediate 'void *' to be a "meaningful"
representation of the 'int *'.
However, all of the "not meaningful" argument is based entirely on the
abstraction of C from assembly and not valid in reality. In reality, all
addressing is based on the underlying cpu and assembly which is usually
ordered thereby making the intermediate 'void *' "meaningful."
Rod Pemberton