指向整数到指针转换的指针 [英] pointer to integer to pointer conversions

查看:96
本文介绍了指向整数到指针转换的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我曾经困扰过你一段关于在void *中存储整数值的问题。现在

在完全不相关的上下文中,我正在尝试以整数类型存储指针值




所以基本的问题是,是否可以将指针转换为

整数,然后再转换(但在相同的执行环境中,即

程序尚未退出,因此它是相同的架构,相同的

编译器,相同的二进制表示等等)从

整数中检索相同的结构。指针(也就是说,指向同一个

对象的指针,如果它保存在某处,则会比较原始指针)?


在我找到的名为ISO / IEC 9899:TC3的文件中,我在

第6.3.2.3段中找到指针可以转换为整数和

反之亦然,只要整数类型足够大,结果

是实现定义的。这是否意味着标准没有

保证转换为一个整数并返回一个指针yeilds

相同的指针?还是写在别的地方?


我认为这个文件是关于C99的,答案不同于

C89?

假设转换可能有效,我应该确保

原始指针和检索到的指针具有完全相同的类型,

或者它是否可以使用一个是给定类型而另一个是

是一个空格*后来转换成了正确类型的指针?


无论如何它都有效,有没有一种可移植的方式来知道什么是整数

类型足够大以保持指针值?


如果重要,我的情况就是我希望,出于调试目的,

输出值指向用户(me)的指针,然后读取

从用户返回的值。让用户处理指针的最自然的方法是打印并将其作为整数读取。当然我

在这种情况下真的不需要便携性,但是我感觉

以后它可能是有用的知识。或许也许我只是过分强调可移植性,就像太多人过分强调

性能一样。

Hi,

I bothered you a while back about storing integer values in void*. Now
in a completely unrelated context, I''m trying to store pointer values
in an integer type.

So the basic question is, is it possible to convert a pointer into an
integer, and then later (but on the same execution environment, ie the
program has not exited, thus it''s the same architecture, same
compiler, same binary representations and so on) retrieve from the
integer the "same" pointer (that is, a pointer that points to the same
object and that would compare equal to the original pointer if it was
kept somewhere)?

On the document I found, named "ISO/IEC 9899:TC3", I have found on
paragraph 6.3.2.3 that pointers can be converted into integers and
vice versa, provided the integer type is large enough, the result
being implementation-defined. Does it mean the standard does not
guarantee that converting to an integer and back to a pointer yeilds
the same pointer? Or is it written somewhere else?

I gather that this document is about C99, is the answer different in
C89?

And supposing that conversion might work, should I make sure the
original pointer and the retrieved pointer have exactly the same type,
or can it work with one them being of a given type and the other one
being a void* later converted into a pointer of the correct type?

In any case it works, is there a portable way to know what integer
types are large enough to hold a pointer value?

In case it matters, my situation is that I want, for debug purposes,
to output the "value" of a pointer to the user (me), and then read
that value back from the user. The most natural way to make a user
handle pointers was to print and read it as an integer. Of course I
don''t really need portability in that case, but I have the feeling
that it might be useful knowledge later on. Or maybe I''m only
overemphasizing portability the same way too many people overemphasize
performance.

推荐答案

5月6日下午3:05,锂... @ gmail.com写道:
On May 6, 3:05 pm, lithium...@gmail.com wrote:




我曾经困扰过你一段关于在void *中存储整数值的问题。现在

在完全不相关的上下文中,我正在尝试以整数类型存储指针值


Hi,

I bothered you a while back about storing integer values in void*. Now
in a completely unrelated context, I''m trying to store pointer values
in an integer type.



这是可能的。使用`intptr_t''或'uintptr_t''。

你必须包含< stdint.h来使用它。

还有uintptr_t,你将用它存储无效指针

无关紧要。

只有你在算术中使用它才有意义。

ie,uintptr_t foo = malloc(123 ); foo = ~foo; free((void *)〜free);

使用intptr_t可能在此示例中调用未定义的行为(例如,

,例如,malloc()返回NULL)

That''s possible. Using `intptr_t'' or `uintptr_t''.
You have to include <stdint.hto use it.
There is also uintptr_t, which you will use to store the void pointer
does not matter.
The type only matters if you use it in arithmetic.
ie, uintptr_t foo = malloc(123); foo = ~foo; free((void*)~free);
With intptr_t undefined behavior might be invoked in this example (if,
for example, malloc() returns NULL)


所以基本的问题是,是否可以将指针转换为

整数,然后再转换(但在相同的执行环境中,即

程序还没有退出,因此它是相同的架构,相同的

编译器,相同的二进制表示等等)从
$中检索b $ b整数相同指针(也就是指向同一个

对象的指针,如果它保存在某处,那么它将与原始指针进行比较)?
So the basic question is, is it possible to convert a pointer into an
integer, and then later (but on the same execution environment, ie the
program has not exited, thus it''s the same architecture, same
compiler, same binary representations and so on) retrieve from the
integer the "same" pointer (that is, a pointer that points to the same
object and that would compare equal to the original pointer if it was
kept somewhere)?



是的,引自ISO 9899:1999,7.18.1.4:

Yep, quote from ISO 9899:1999, 7.18.1.4:


以下类型表示a (un)带有属性

的有符号整数类型,任何有效的void指针都可以转换为这种类型,然后转换为

返回指向void的指针,结果将比较等于原始指针。
The following type designates a (un)signed integer type with the property
that any valid pointer to void can be converted to this type, then converted
back to pointer to void, and the result will compare equal to the originalpointer.



(关于intptr_t和uintptr_t)

(regarding intptr_t and uintptr_t)


在我找到的文件中,命名为ISO / IEC 9899:TC3,我在

第6.3.2.3段中发现指针可以转换成整数而

反之亦然,只要整数类型足够大,结果

是实现定义的。这是否意味着标准没有

保证转换为一个整数并返回一个指针yeilds

相同的指针?还是写在别的地方?
On the document I found, named "ISO/IEC 9899:TC3", I have found on
paragraph 6.3.2.3 that pointers can be converted into integers and
vice versa, provided the integer type is large enough, the result
being implementation-defined. Does it mean the standard does not
guarantee that converting to an integer and back to a pointer yeilds
the same pointer? Or is it written somewhere else?



从6.3.2.3开始:

From 6.3.2.3:


任何指针类型都可以转换为整数类型。除了之前的特定情况,

结果是实现 - 定义。如果结果不能用整数类型表示,那么行为是未定义的。结果不必在任何整数

类型的值范围内。
Any pointer type may be converted to an integer type. Except as previouslyspeci???ed, the
result is implementation-de???ned. If the result cannot be represented in the integer type,
the behavior is unde???ned. The result need not be in the range of values of any integer
type.



这意味着使用intptr_t以外的任何整数类型是不安全的!

即使uintmax_t可以调用未定义的行为,当有是没有

intptr_t或uintptr_t提供(它们是可选类型),并且当

指针大于实现中的最大整数类型时。

That means it''s not safe to use any integer type other than intptr_t!
Even uintmax_t can invoke undefined behavior, when there is no
intptr_t or uintptr_t provided (they are optional types), and when a
pointer is larger than the largest integer type in the implementation.


我认为这个文件是关于C99的,答案不同于

C89?
I gather that this document is about C99, is the answer different in
C89?



C89中没有答案。在较旧的代码中,使用了unsigned long,但

也不安全。

很明显它用于了解细节的地方。

(编译器,平台等)

There''s no answer in C89. In older code, unsigned long was used, but
that''s not safe either.
It was obviously used it places where the details were known.
(compiler, platform, etc)


假设转换可能有效,我应该确定

原始指针和检索到的指针具有完全相同的类型,

或者它可以使用一个属于给定类型而另一个

是一个void *后来转换为指针正确的类型?
And supposing that conversion might work, should I make sure the
original pointer and the retrieved pointer have exactly the same type,
or can it work with one them being of a given type and the other one
being a void* later converted into a pointer of the correct type?



在将指针分配给

uintptr_t或intptr_t之前,必须将指针强制转换为void *。

You have to cast the pointer to `void *'' before you assign it to a
uintptr_t or intptr_t.


无论如何它是否有效,是否有一种可移植的方式来知道什么整数

类型足够大以保存指针值?
In any case it works, is there a portable way to know what integer
types are large enough to hold a pointer value?



编号

No.


如果重要,我的情况是我想要的,出于调试目的,

输出值指向用户(me)的指针,然后读取

从用户返回的值。让用户处理指针的最自然的方法是打印并将其作为整数读取。当然我

在这种情况下真的不需要便携性,但是我感觉

以后它可能是有用的知识。或者也许我只是过分强调可移植性,就像太多人过分强调性能一样。
In case it matters, my situation is that I want, for debug purposes,
to output the "value" of a pointer to the user (me), and then read
that value back from the user. The most natural way to make a user
handle pointers was to print and read it as an integer. Of course I
don''t really need portability in that case, but I have the feeling
that it might be useful knowledge later on. Or maybe I''m only
overemphasizing portability the same way too many people overemphasize
performance.



您还可以在printf和scanf中使用'p''转换说明符,例如

函数,这可能是最好的解决方案你的问题,

,因为它也适用于C89,你不必担心uintptr_t / intptr_t的可用性。

另外,是的:可以用%p写一个指向文件流的指针,然后读回来。

You can also use the `p'' conversion specifier in printf and scanf like
functions, which would probably be the best solution for your problem,
because it will also work in C89, and you don''t have to worry about
the availability of uintptr_t/intptr_t.
Also, yes: It is possible to write a pointer to a file stream with %p,
then read it back.


< a href =mailto:li ******** @ gmail.com> li ******** @ gmail.com 写道:




我曾经困扰过你一段关于在void *中存储整数值的问题。现在

在完全不相关的上下文中,我正在尝试以整数类型存储指针值




所以基本的问题是,是否可以将指针转换为

整数,然后再转换(但在相同的执行环境中,即

程序尚未退出,因此它是相同的架构,相同的

编译器,相同的二进制表示等等)从

整数中检索相同的结构。指针(也就是指向同一个

对象的指针,如果它保存在某处,那么它将与原始指针进行比较)?
Hi,

I bothered you a while back about storing integer values in void*. Now
in a completely unrelated context, I''m trying to store pointer values
in an integer type.

So the basic question is, is it possible to convert a pointer into an
integer, and then later (but on the same execution environment, ie the
program has not exited, thus it''s the same architecture, same
compiler, same binary representations and so on) retrieve from the
integer the "same" pointer (that is, a pointer that points to the same
object and that would compare equal to the original pointer if it was
kept somewhere)?



它取决于。


在C89 / C90 / ANSI中,从数据指针转换为整数和<允许返回
,但是没有保证价值

你会得到并且不能保证任何给定的值能够存活

往返。 (非生存的最常见原因是

整数太短:一个程序将指针转换为

32位整数发现自己被移植到一台64机器上比特指针。)


C99改善了这种情况,但只是一点点。如果存在整数

类型intptr_t和uintptr_t,那么任何有效的void *都可以转换为其中一个并返回其中一个并重新运行。

(无法保证无效指针,也无法将

转换为void *并返回任意整数值。)但是,请注意,这些整数类型是

是可选的:如果它们存在,它们将按照你想要的那样工作,但是在一些异国情调中。他们可能缺席的架构。

"It depends."

In C89/C90/ANSI, conversions from data pointer to integer and
back are permitted, but there are no guarantees about the values
you''ll get and no guarantees that any given value will survive
the round-trip. (The commonest reason for non-survival is that
the integer is too short: a program that converted pointers to
32-bit ints finds itself ported to a machine with 64-bit pointers.)

C99 improves the situation, but only a little. If the integer
types intptr_t and uintptr_t exist, then any valid void* can be
converted to one of them and back again and survive the journey.
(There are no guarantees for invalid pointers, nor for converting
an arbitrary integer value to void* and back.) Note, though, that
these integer types are optional: If they exist they will work as
you desire, but on some "exotic" architecture they might be absent.


假设转换可能有效,我应该确保

原始指针和检索到的指针完全正确相同的类型,

或者它可以使用一个属于给定类型的另一个

是一个void *后来转换为正确类型的指针?
And supposing that conversion might work, should I make sure the
original pointer and the retrieved pointer have exactly the same type,
or can it work with one them being of a given type and the other one
being a void* later converted into a pointer of the correct type?



intptr_t和uintptr_t上的操作仅针对

有效的void *值定义,但有效的AnyData *始终可以转换为

无效*并且没有伤害。所以你应该写


AnyData * p =& what,* q;

uintptr_t ip;

ip =(uintptr_t )(void *)p;

q =(void *)ip;

断言(p == q);


据我所知,所有演员阵容都是必要的。

The operations on intptr_t and uintptr_t are defined only for
valid void* values, but a valid AnyData* can always be converted
to void* and back without harm. So you should write

AnyData *p = &whatever, *q;
uintptr_t ip;
ip = (uintptr_t)(void*)p;
q = (void*)ip;
assert (p == q);

As far as I can tell, all the casts are necessary.


无论如何它都有效,是否有一种可移植的方式来知道什么是整数

类型是否足以容纳指针值?
In any case it works, is there a portable way to know what integer
types are large enough to hold a pointer value?



对于C99,intptr_t和uintptr_t是答案。我不能用b $ b想到一种西蒙纯粹的方法来解决早期标准的问题。

For C99, intptr_t and uintptr_t are the answers. I cannot
think of a Simon-pure way to solve the problem for earlier Standards.


如果重要,我的情况就是那样出于调试目的,我希望输出b值来输出值。指向用户(me)的指针,然后读取

从用户返回的值。让用户处理指针的最自然的方法是打印并将其作为整数读取。当然我

在这种情况下真的不需要便携性,但是我感觉

以后它可能是有用的知识。或者也许我只是过分强调可移植性,就像太多人过分强调性能一样。
In case it matters, my situation is that I want, for debug purposes,
to output the "value" of a pointer to the user (me), and then read
that value back from the user. The most natural way to make a user
handle pointers was to print and read it as an integer. Of course I
don''t really need portability in that case, but I have the feeling
that it might be useful knowledge later on. Or maybe I''m only
overemphasizing portability the same way too many people overemphasize
performance.



即使在C89中,您也可以使用%p打印一个void *值。你还可以用%p来扫描它。 (匹配void **),但结果

没有用。 C99(或者可能是中级修订版)

收紧语言要求往返必须成功

如果一切都有效,程序还没有退出,

指向的位置仍然有效,依此类推。


我能理解你为什么要将指针值显示为

a调试助手,但是想要再次阅读它们似乎很奇怪

。 Chancy也是:一个无辜的错字引起了鼻子的恶魔。


-

Eric Sosman
es ***** @ ieee-dot-org.inva 盖子


谢谢大家为了你的答案,他们真的很有帮助。似乎

6.3.2.3并非全部。


虽然这是非常偏离主题的,你能告诉我那是什么吗? />
ISO / IEC 1999:TC3值得?我可以把它作为参考吗?如果是这样,是否有一个类似的C89参考?


5月6日下午2:37,Eric Sosman< esos ... @ ieee -dot-org.invalidwrote:
Thanks you all for your answers, they were really helpful. It seems
that 6.3.2.3 wasn''t all.

Although it''s quite off-topic, could you tell me what that
"ISO/IEC 1999:TC3" is worth? Can I take it as a reference? If so, is
there a similar reference for C89?

On May 6, 2:37 pm, Eric Sosman <esos...@ieee-dot-org.invalidwrote:

即使在C89中,你也可以使用%p打印一个void *值。你还可以用%p来扫描它。 (匹配void **),但结果

没有用。 C99(或者可能是中级修订版)

收紧语言要求往返必须成功

如果一切都有效,程序还没有退出,

指向的位置仍然有效,依此类推。
Even in C89 you could printf a void* value with "%p". You
could also scanf it with "%p" (matching a void**), but the result
was not usefully defined. C99 (or maybe an intermediate revision)
tightened the language to require that the round-trip must succeed
if everything was valid to begin with, the program hasn''t exited,
the pointed-to location is still valid, and so on.



非常感谢这个想法,我甚至都没有考虑过。我已经

实际上从未使用任何类似scanf的功能。我不喜欢使用

我不理解的东西,这些功能对我来说有点像魔术一样。我会深入研究这个方向。


现在我想起来了,我犯了一个错误,只考虑

给用户指针作为一个int ,实际上我想

将它作为一个可打印的字符串。

Thanks a lot for the idea, I haven''t even considered it. I''ve
actually never used any scanf-like function. I don''t like using
things I don''t understand, and these functions looks a little bit
like magic to me. I will dig into that direction.

Now that I think about it, I made the mistake of only considering
giving the pointer to the user as an int, while actually I want to
give it as a printable string.


我能理解你为什么要显示指针值作为

a调试辅助工具,但想要再次阅读它们似乎很奇怪

。 Chancy也是:一个无辜的错字引起了鼻子的恶魔。
I can understand why you''d want to display pointer values as
a debugging aid, but it seems peculiar to want to read them back
again. Chancy, too: An innocent typo arouses the nasal demons.



我不知道这是通常还是好方法,但我喜欢

测试部分我的程序手工,没有任何输入santization

和尽可能少的处理(我想测试我的程序的部分

,而不是草稿输入我把它用于测试/调试

目的)。在这些情况下,无辜的错字是指无辜的错字。只是意味着我不能从测试中推断出任何东西,这并不是那么糟糕(尽管

我应该认为自己很幸运只遇到程序

段错误是未定义行为的表现,而不是例如

大规模核爆炸。

I don''t know if it''s a usual or good way to do it, but I like to
test parts of my programs "by hand", without any input santization
and as little processing as possible (I want to test the part of
my program, not the draft-input I put on it for testing/debugging
purpose). In these cases, an "innocent typo" only means that I
can''t deduce anything from the test, which isn''t that bad (though
I should probably consider myself lucky to encounter only program
segfaults as manifestations of undefined behaviour, and not e.g.
large-scale nuclear explosions).


这篇关于指向整数到指针转换的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆