简体   繁体   English

以下语句是否将物理地址或虚拟地址分配给指针?

[英]Do the following statements assign either physical or virtual address to a pointer?

From https://stackoverflow.com/a/2761494/156458 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. C和C ++都没有提供严格定义的功能,该功能不允许您将特定的物理地址分配给指针。 So your question about "how one would assign 0 address to a pointer" formally has no answer. 因此,您有关“如何将0地址分配给指针”的问题正式没有答案。 You simply can't assign a specific address to a pointer in C/C++. 您根本无法为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. 前者通常会产生一个指向物理地址0的指针,该地址可能为也可能不是给定平台上的空指针值。

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. 我很惊讶地发现void *p = 0并没有分配物理或虚拟地址0,而是将空指针void分配给了指针。

The quote also says that the "explicit integer-to-pointer conversion" can assign an address to a pointer. 引号还说,“显式整数到指针转换”可以为指针分配地址。

Questions: 问题:

  1. in void *p = 0 , is there implicit conversion from 0 to void* ? void *p = 0 ,是否存在从0void*隐式转换?

    Is the implicit conversion the same as explicit conversion (void *)0 , ie is void *p = 0 the same as void *p = (void*) 0 ? 隐式转换是否与显式转换(void *)0 ,即void *p = 0void *p = (void*) 0吗?

    Does void *p = (void*) 0 produce a pointer to either physical or virtual address 0 or a null pointer of void ? void *p = (void*) 0产生指向物理地址或虚拟地址0的指针或void的空指针?

  2. If I use a nonzero number, eg void *p = 123 , is there implicit conversion from 123 to void * ? 如果我使用非零数字,例如void *p = 123 ,是否存在从123void *隐式转换?

    Is the implicit conversion the same as explicit conversion (void *) 123 ? 隐式转换与显式转换(void *) 123吗?

    Will either void *p = 123 or void *p = (void *)123 make p a pointer to either physical or virtual address 123 ? void *p = 123void *p = (void *)123会使p指向物理或虚拟地址123的指针吗?

    If void *p = (void *)123 can't generate a pointer to either physical or virtual address 123 , can int addr = 123; void *p = (void *)addr; 如果void *p = (void *)123无法生成指向物理或虚拟地址123的指针,则可以int addr = 123; void *p = (void *)addr; int addr = 123; void *p = (void *)addr; ? I create it by replacing unitptr_t with int in the first example in the quote. 我通过在引用的第一个示例中将int替换为unitptr_t创建它。

Thanks. 谢谢。

If you say 如果你说

char *p = 0x12345;

you will probably assign p to point to address 0x12345 . 您可能会分配p指向地址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 . 同样,这将分配p指向地址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 ? 问题是,您是否已分配p指向地址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 . 不是说p = 0 不会分配p指向地址0 ,而是可能不会 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. 在空指针的内部表示形式不是全零的机器上,分配p = 0会将p设置为该空指针值,因此p 不会指向地址0。

TL;DR: Most of what you are asking about is in the realm of implementation-specific behavior and language extensions. TL; DR:您所要求的大部分是特定于实现的行为和语言扩展领域。 Consult your compiler documentation if you have genuine need for such behaviors. 如果您确实需要这种行为,请查阅编译器文档。

  1. in void *p = 0 , is there implicit conversion from 0 to void* ? void *p = 0 ,是否存在从0void*隐式转换?

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 * . 那些确实定义了所需结果的人,但实际上,它们确实提供了对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 * . 因为文字0是“空指针常量”,因为初始化程序执行与简单赋值相同的转换,并且因为简单赋值为将空指针常量赋值给指针提供了特殊情况,所以, 0被隐式转换为void * Furthermore, because 0 is a null pointer constant, such a conversion results in a null pointer of type void * . 此外,因为0是空指针常量,所以这种转换会导致类型为void *的空指针。

Is the implicit conversion the same as explicit conversion (void *)0 , ie is void *p = 0 the same as void *p = (void*) 0 ? 隐式转换是否与显式转换(void *)0 ,即void *p = 0void *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. C无处可区分通过强制转换和相同类型之间的自动转换显式指定的转换效果。

Does void *p = (void*) 0 produce a pointer to either physical or virtual address 0 or a null pointer of void ? void *p = (void*) 0产生指向物理地址或虚拟地址0的指针或void的空指针?

It initializes p to contain a null pointer (of type void * ). 它初始化p包含一个空指针(类型为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. 根据C,空指针不会指向任何对象,并且C除了对象或函数的地址之外没有任何地址意义,因此至少在这种意义上,将此类指针解释为指向任何特定地址是不正确的。 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. 取消引用这样的指针的效果不是由C定义的,而是可以由某些实现定义的-可能试图访问地址0的对象。

  1. If I use a nonzero number, eg void *p = 123 , is there implicit conversion from 123 to void * ? 如果我使用非零数字,例如void *p = 123 ,是否存在从123void *隐式转换?

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 ? 隐式转换与显式转换(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 or void *p = (void *)123 make p a pointer to either physical or virtual address 123 ? void *p = 123void *p = (void *)123会使p指向物理或虚拟地址123的指针吗?

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. 同样,C除了对象或函数的地址之外,没有其他意义的地址,特别是它本身拒绝指定将整数转换为指针类型的结果,除了首先通过将指针转换为整数而获得的整数外,对于值为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. 但是,在某些实现中,将整数(值为0的整数常量除外)转换为指针具有将整数解释为地址,并转换为指向该地址的指针的效果,就像存在一个带有该地址的对象一样地址。 In a hosted C implementation, this will typically be a virtual address. 托管 C实现中,这通常是虚拟地址。 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. 一些实现方式也可以将此行为扩展为值为0的整数常量,该常数可能或可能不是固有地不一致。

If void *p = (void *)123 can't generate a pointer to either physical or virtual address 123 , can int addr = 123; void *p = (void *)addr; 如果void *p = (void *)123无法生成指向物理或虚拟地址123的指针,则可以int addr = 123; void *p = (void *)addr; int addr = 123; void *p = (void *)addr; ? I create it by replacing unitptr_t with int in the first example in the quote. 我通过在引用的第一个示例中将int替换为unitptr_t创建它。

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. 完全有理由期望,显式转换值为123的int变量的结果与显式转换值为123的整数常量的结果完全相同,但是从技术上讲,它是实现定义的,可能为编译器提供了遵循的空间。区分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM