问题
From https://stackoverflow.com/a/2761494/156458
neither C nor C++ provides a strictly defined feature that would allow you to assign a specific physical address to a pointer. So your question about "how one would assign 0 address to a pointer" formally has no answer. You simply can't assign a specific address to a pointer in C/C++. However, in the realm of implementation-defined features, the explicit integer-to-pointer conversion is intended to have that effect. So, you'd do it as follows
uintptr_t address = 0; void *p = (void *) address;
Note, that this is not the same as doing
void *p = 0;
The latter always produces the null-pointer value, while the former in general case does not. The former will normally produce a pointer to physical address 0, which might or might not be the null-pointer value on the given platform.
I am surprised to find it out that void *p = 0
doesn't assign either physical or virtual address 0 but a null pointer of void
to the pointer.
The quote also says that the "explicit integer-to-pointer conversion" can assign an address to a pointer.
Questions:
in
void *p = 0
, is there implicit conversion from0
tovoid*
?Is the implicit conversion the same as explicit conversion
(void *)0
, i.e. isvoid *p = 0
the same asvoid *p = (void*) 0
?Does
void *p = (void*) 0
produce a pointer to either physical or virtual address 0 or a null pointer ofvoid
?If I use a nonzero number, e.g.
void *p = 123
, is there implicit conversion from123
tovoid *
?Is the implicit conversion the same as explicit conversion
(void *) 123
?Will either
void *p = 123
orvoid *p = (void *)123
makep
a pointer to either physical or virtual address123
?If
void *p = (void *)123
can't generate a pointer to either physical or virtual address123
, canint addr = 123; void *p = (void *)addr;
? I create it by replacingunitptr_t
withint
in the first example in the quote.
Thanks.
回答1:
If you say
char *p = 0x12345;
you will probably assign p
to point to address 0x12345
. Whether that's a virtual or a physical address we can't say; that depends on your machine and how it's configured. (But if your machine uses virtual memory, and if you're writing an ordinary user program, then it's certainly a virtual address.)
In the above I said "probably", in part because assigning an integer to a pointer is not, strictly speaking, well-defined. So to be on the safe side, you would write
char *p = (char *)0x12345;
This will, again, assign p
to point to address 0x12345
.
But then we come to the special cases. If you write
char *p = 0;
or
char *p = (char *)0;
the question is, have you assigned p
to point to address 0
? And the answer is, probably, on any conventional machine, but this is not guaranteed, because there's a special case for null pointers.
It's not that p = 0
will not assign p
to point to address 0
-- it's that it might not. On a machine where the internal representation of a null pointer is not all-bits-0, the assignment p = 0
will set p
to that null pointer value, and p
will therefore not point to address 0.
回答2:
TL;DR: Most of what you are asking about is in the realm of implementation-specific behavior and language extensions. Consult your compiler documentation if you have genuine need for such behaviors.
- in
void *p = 0
, is there implicit conversion from0
tovoid*
?
The initialization is non-conforming, but many compilers accept it as an extension. Those that do define the result however they want, but in practice they indeed provide an implicit conversion to void *
.
Because literal 0
is a "null pointer constant", because initializers perform the same conversions that simple assignment does, and because simple assignment has a special-case provision for assigning null pointer constants to pointers, yes, 0
is implicitly converted to type void *
. Furthermore, because 0
is a null pointer constant, such a conversion results in a null pointer of type void *
.
Is the implicit conversion the same as explicit conversion
(void *)0
, i.e. isvoid *p = 0
the same asvoid *p = (void*) 0
?
There is good reason to expect that a compiler that accepts the former form will treat it exactly the same as the latter form, but again, the former is non-conforming and implementations that accept it as an extension define their own semantics for it.
Yes. C nowhere distinguishes between the effects of conversions specified explicitly via casts and automatic conversions between the same types.
Does
void *p = (void*) 0
produce a pointer to either physical or virtual address 0 or a null pointer ofvoid
?
It initializes p
to contain a null pointer (of type void *
). According to C, a null pointer does not point to any object, and C has no sense of addresses apart from those of objects or functions, so in at least this sense it is incorrect to interpret such a pointer as pointing to any particular address. The effect of dereferencing such a pointer is not defined by C, but it might be defined by some implementations -- possibly to attempt to access an object at address 0.
- If I use a nonzero number, e.g.
void *p = 123
, is there implicit conversion from123
tovoid *
?
That initialization is non-conforming, but some compilers provide an implicit conversion as an extension.
Is the implicit conversion the same as explicit conversion
(void *) 123
?
There is very good reason to expect that to be the case with a compiler that implements such an implicit conversion at all, but again, "extension".
Will either
void *p = 123
orvoid *p = (void *)123
makep
a pointer to either physical or virtual address123
?
That is implementation-defined. Again, C has no sense of addresses apart from those of objects or functions, and in particular it itself declines to specify the result of converting an integer to a pointer type, except for integers obtained by converting a pointer to integer in the first place, and for integer constant expressions with value 0.
On some implementations, however, converting an integer (other than an integer constant with value 0) to a pointer has the effect of interpreting the integer as an address, and converting to a pointer to that address, as if there were an object with that address. In a hosted C implementation, this will typically be a virtual address. In a standalone implementation, it will typically be a physical address. Some of implementations may extend this behavior to integer constants with value 0, too, which may or may not be inherently non-conforming.
If
void *p = (void *)123
can't generate a pointer to either physical or virtual address123
, canint addr = 123; void *p = (void *)addr;
? I create it by replacingunitptr_t
with int in the first example in the quote.
There is every reason to expect that the result of explicitly converting an int
variable with value 123 is exactly the same as that of explicitly converting an integer constant with value 123, but, technically, that it is implementation defined may leave room for conforming compilers to distinguish.
来源:https://stackoverflow.com/questions/52207010/do-the-following-statements-assign-either-physical-or-virtual-address-to-a-point