一些指针再次停顿 [英] Some pointer quiestions again

查看:67
本文介绍了一些指针再次停顿的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据A6.6节指针和整数(k& R)


"指向一种类型的指针可能会转换为指向另一种类型的指针。

如果主题指针未引用

寻址异常>
对象在存储中适当对齐。保证指向某个对象的指针可以转换为指向

的对象,其类型需要较少的b / b
或同样严格的存储空间是

对齐,然后再没有改变;

'`alignment''''的概念是

依赖于实现,但char类型的对象具有最少的

严格的对齐要求。在Par.A.6.8中描述的

,指针也可以转换为void *

类型,然后再返回而不做任何更改。


它表示*保证*指向对象的指针可以转换为类型要求同样严格的对象
存储对齐。我的问题是,因为两个指针变量

可能有不同的大小(正如很多人指出的那样,这个新闻组中的b $ b)这怎么可能呢?有可能

不同类型的两个指针变量具有相同的

字节对齐限制,但它们的大小可能不同。在

这些条件下我们如何将一个转换为另一个?


我会说两个不同类型的指针变量

应该永远不允许从一种类型转换为另一种类型,因为

相同的字节对齐并不意味着相同的指针变量大小。


其次,A.6.8节说那个以前的char *指针

扮演了通用(无效)指针的角色

现在这也是真的吗?

考虑以下一段代码:

#include< stdlib.h>

int main(无效)

{

unsigned char * c;

int * i;


i = malloc(sizeof(int));

c = i; < br $>
}


在comlilation上,我收到警告,

cc:警告:tc,第8行:在本声明中,引用类型的

指针值i是int,与unsigned

char不兼容。 (ptrmismatch)

c = i;

-------- ^


如果char指针可以起作用通用指针,为什么我得到这个警告?

According to Section A6.6 Pointers and Integers (k & R)

" A pointer to one type may be converted to a pointer to another type.
The resulting pointer may cause
addressing exceptions if the subject pointer does not refer to an
object suitably aligned in storage. It is
guaranteed that a pointer to an object may be converted to a pointer to
an object whose type requires less
or equally strict storage alignment and back again without change; the
notion of ``alignment'''' is
implementation-dependent, but objects of the char types have least
strict alignment requirements. As
described in Par.A.6.8, a pointer may also be converted to type void *
and back again without change. "

It says that it is *guaranteed* that a pointer to an object may
be converted to an object whose type require equally stringent
storage alignment. My question is that since two pointer variables
may be of different size (as pointed out by lots of people
in this newsgroup ) how this could be possible ? It may be possible
that two pointer variables of different types have same
byte alignment restrictions but their sizes may be different. Under
these conditions how can we convert one to another ?

I would say that two pointer variables of different types
should never be allowed to convert from one type to other, because
same byte alignment does not mean same pointer variable size.

Secondly, section A.6.8 says that "previously char * pointers
played the role of generic (void) pointers"
Is this true presently also ?
Consider the following piece of code:
#include <stdlib.h>
int main(void)
{
unsigned char *c;
int *i;

i = malloc(sizeof(int));
c = i;
}

On comlilation, I get the warning,
cc: Warning: t.c, line 8: In this statement, the referenced type of the
pointer value "i" is "int", which is not compatible with "unsigned
char". (ptrmismatch)
c = i;
--------^

If char pointer can play the role of generic pointer, why I
am getting this warning ?

推荐答案

ju ********** @ yahoo.co.in 写道:
根据A6.6节指针和整数(k& R)
"指向一种类型的指针可以转换为指向另一种类型的指针。
如果主题指针没有引用在存储中适当对齐的对象,则结果指针可能导致解决异常。保证指向对象的指针可以转换为指向一个对象,该对象的类型需要较少的
或同样严格的存储对齐,然后再返回而不进行更改; 对齐的概念取决于实现,但是char类型的对象具有最少的严格对齐要求。如在参数A.6.8中描述的那样,指针也可以转换为void *
类型,然后再返回而不做任何更改。 "
它表示*保证*指向对象的指针可以转换为类型需要同样严格的存储对齐的对象。我的问题是,由于两个指针变量
可能具有不同的大小(正如许多人在这个新闻组中指出的那样),这怎么可能呢?有可能两个不同类型的指针变量具有相同的字节对齐限制,但它们的大小可能不同。在
这些条件下,我们如何将一个转换为另一个?
我会说不应该允许两个不同类型的指针变量从一种类型转换为另一种类型,因为相同的字节对齐并不意味着相同的指针变量大小。


如果大小不同,编译器必须插入代码(你应该

,但不必通过强制转换告诉它)来使转换工作

正确。但是,如果你转换成的类型的对齐 -

限制并不比你那种类型的b / b更严格,那么它只需要合理地这样做。从...转换。位代表转换表示指针并不罕见,例如:一个NULL指针并不是
必须有一个二进制表示,其中所有位都是0,但是你可以比较一个NULL指针(例如从malloc()返回)

无论如何都是值0并且结果必须为true,即使转换为int(假设大小相等)时

NULL指针也不会

导致数字0 [1]。因此,编译器必须插入代码,使得b / b $ b使得这种比较的结果正确。并且对于

类型的指针之间的合法转换(即满足上述关于对齐 -

限制的规则)存储有不同大小的编译器还必须确保

这是正确的,如果它是标准的兼容C编译器[2]。

其次,A.6.8节说以前的char *指针
扮演了通用(无效)指针的角色
目前这也是真的吗?
考虑以下代码:
#include< stdlib.h>
int main(void)
{
unsigned char * c;
int * i;
i = malloc(sizeof(int));
c = i;
}
在comlilation上,我收到警告,
cc:警告:tc,第8行:在此语句中,
指针值i的引用类型。是int,它与unsigned
char不兼容。 (ptrmismatch)
c = i;
-------- ^
如果char指针可以起到通用指针的作用,为什么我得到这个警告?
According to Section A6.6 Pointers and Integers (k & R) " A pointer to one type may be converted to a pointer to another type.
The resulting pointer may cause
addressing exceptions if the subject pointer does not refer to an
object suitably aligned in storage. It is
guaranteed that a pointer to an object may be converted to a pointer to
an object whose type requires less
or equally strict storage alignment and back again without change; the
notion of ``alignment'''' is
implementation-dependent, but objects of the char types have least
strict alignment requirements. As
described in Par.A.6.8, a pointer may also be converted to type void *
and back again without change. " It says that it is *guaranteed* that a pointer to an object may
be converted to an object whose type require equally stringent
storage alignment. My question is that since two pointer variables
may be of different size (as pointed out by lots of people
in this newsgroup ) how this could be possible ? It may be possible
that two pointer variables of different types have same
byte alignment restrictions but their sizes may be different. Under
these conditions how can we convert one to another ? I would say that two pointer variables of different types
should never be allowed to convert from one type to other, because
same byte alignment does not mean same pointer variable size.
If the sizes differ the compiler has to insert code (you should
but don''t have to tell it by casting) to make the conversion work
out right. But it''s only required to do so reasonably if the align-
ment restrictions of the type you convert to aren''t stricter than
of the type you''re converting from. A conversion of bit represen-
tations of pointers is not uncommon, e.g. a NULL pointer doesn''t
have to have a binary representation where all bits are 0, but you
can compare a NULL pointer (e.g. returned by from malloc()) with
the value 0 anyway and the result must be true, even though the
NULL pointer when cast to an int (assuming equal sizes) wouldn''t
result in the number 0 [1]. So the compiler has to insert code that
makes the result of this comparison come out correctly. And for a
legitimate conversion (i.e. one where the above rules about align-
ment restrictions are satisfied) between pointers of types which are
stored with different sizes the compiler also has to ensure that
this works correctly if it''s a standard compliant C compiler [2].
Secondly, section A.6.8 says that "previously char * pointers
played the role of generic (void) pointers"
Is this true presently also ?
Consider the following piece of code:
#include <stdlib.h>
int main(void)
{
unsigned char *c;
int *i; i = malloc(sizeof(int));
c = i;
} On comlilation, I get the warning,
cc: Warning: t.c, line 8: In this statement, the referenced type of the
pointer value "i" is "int", which is not compatible with "unsigned
char". (ptrmismatch)
c = i;
--------^ If char pointer can play the role of generic pointer, why I
am getting this warning ?




这是一个警告,而不是一个错误,告诉你,你可能正在做一些愚蠢的事情。不多也不少。编译器可能会假定你知道你在做什么时会做什么,当你用一个显式的强制转换(但它仍然会发出一个警告) ,那里

对编译器可以投诉的标准没有限制),

所以它可能让你逃脱一个明确的演员。但是由于不同类型之间的分配是有潜在危险的,因此编译器会尝试帮助您。如果(x = malloc(100 * sizeof * x)),它就像获得一个战争 -


一样>

这没有什么本质上的错误,但大多数编译器会

仍然告诉你,你可能会无意间做任务

而不是在这里比较,因为'=''和''==''混合起来

在if条件下是如此常见的错误。


此外,正如你自己引用的那样,char指针先前指的是播放了

通用指针的作用 - 那是在C标准出现之前

out,最后使void指针类型成为强制性的并给出

it一些神奇的品质,即要求所有指针类型

都可以转换为无效指针(代价为

你不能取消引用无效指针) 。实际上,一个char指针

仍然必须具有相同的表示和对齐要求 -

作为一个void指针,但是因为char指针不是很糟糕

mans" ersatz"对于一个真正的通用指针,不再需要编译器指示

来指示从一个字符指针隐式转换到

不同的指针类型是可疑的。


问候,Jens


[1]这也是为什么在使用malloc时忘记包含< stdlib.h>

的原因( )而不是铸造返回值

不能保证工作。如果< stdlib.h>不包含

编译器假定malloc()返回一个int,因此mind-

将malloc()的返回值转换为int(per-

甚至通过数据将值传递给调用者

仅寄存器 - 有几种架构具有

不同的数据寄存器和地址)。只有这样才能显式转换,现在从int转换为

预期的指针类型。但是,由于指针不一定与
相同,因此当它被解释为int时,这个

会导致有趣。可能是意想不到的结果,

,例如malloc()返回的NULL指针转换为机器上的非NULL指针,其中NULL指针是

并非由所有位0表示。


[2]显然,​​用于机器的编译器的实现者

不同的指针类型有不同的大小有一些问题

他的手中。一种可能的解决方案是使用最大指针类型所需的大小

来存储所有指针,即使这会花费一些额外的内存。另外一个

就是放弃一个写一个标准兼容的C com-

piler就像他们为DOS做的那样,他们发明了新的限定符

指针(即远,巨大等)。或者也许在目标

机器上有一些特殊的技巧来解决问题

(即有一个特殊的位存储小尺寸的指针

当来自较大尺寸指针

的指针值存储在其中然后表明它没有持有

真实地址时,它会被设置指向另一个地址的指针,其中可以找到

的全尺寸地址。并且可能有一些我不知道的更聪明的方式,而不是一个C编译器

实现者。

-

\ Jens Thoms Toerring ___ Je *********** @ physik.fu-berlin.de

\ __________________________ http://www.toerring.de



It''s a warning, not an error, telling you that you may be doing
something stupid. Not more and not less. The compiler will probably
assume that you know what you''re doing when you would do the conver-
sion with an explicit cast (but it still could emit a warning, there
is no restriction in the standard what a compiler can complain about),
so it might let you get away with an explicit cast. But since an
assignment between different types is something potentially dangerous
the compiler here tries to help you. It''s the same as getting a war-
ning for e.g.

if ( x = malloc( 100 * sizeof *x ) )

There''s nothing inherently wrong with this, but most compilers will
still tell you that you may unintenionally be doing an assignment
instead of a comparison here since getting ''='' and ''=='' mixed up
in an if-condition is such a common mistake.

Moreover, as you cite yourself, char pointers "previously" played
the role of generic pointers - that was before the C standard came
out, finally making the void pointer type mandatory and giving
it some magical qualities, i.e. requiring that all pointer types
can be converted to and from a void pointer (at the cost that
you can''t dereference a void pointer). Actually, a char pointer
still has to have the same representation and alignment require-
ments as a void pointer, but since char pointers aren''t a poor
mans "ersatz" for a true generic pointer anymore compilers tend
to point out also implicit conversions to a char pointer from a
different pointer type as suspicious.

Regards, Jens

[1] This is also the reason why forgetting to include <stdlib.h>
when you use malloc() and instead casting the return value
is not guaranteed to work. If <stdlib.h> isn''t included the
compiler assumes that malloc() returns an int and thus mind-
lessly converts the return value of malloc() to an int (per-
haps even passing the value back to the caller via an data
only register - there are several architectures that have
different registers for data and addresses). Only then it does
the explicit conversion, now converting from an int to the
intended pointer type. But since a pointer is not necessarily
the same as its representation when interpreted as an int this
can result in "interesting" and probably unintended results,
e.g. a NULL pointer returned by malloc() becoming converted
to a non-NULL pointer on a machine where a NULL pointer is
not represented by all bits 0.

[2] Obviously, the implementor of a compiler for a machine where
different pointer types have different sizes has some problems
on his hands. One possible solution would by to use the size
required by the largest pointer type for storing all pointers,
even if that would cost some additional memory. Another one
would be to give up one writing a standard compliant C com-
piler like they did for DOS, where they invented new qualifiers
for pointers (i.e. far, huge etc.). Or perhaps on the target
machine there are some special tricks to solve the problem
(i.e. having a special bit stored with small sized pointers
that gets set when a pointer value from a larger sized pointer
gets stored in it and then indicates that it doesn''t hold the
"real" address but just a pointer to another address where the
full-sized address can be found. And there are probably some
more clever ways I wouldn''t know about, not being a C compiler
implementor.
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de

2005年5月31日星期二17:45:08 +0000,Jens.Toerring写道:


[snip]
On Tue, 31 May 2005 17:45:08 +0000, Jens.Toerring wrote:

[snip]
[...]要求所有指针类型
都可以转换为无效指针[...]
[...] requiring that all pointer types
can be converted to and from a void pointer [...]




难道这不应该是所有_object_指针类型或类似

的东西吗?我得到的是ISTR,你无法在虚拟指针中存储函数

指针。


--Mac


Mac< fo*@bar.net>写道:
Mac <fo*@bar.net> wrote:
2005年5月31日星期二17:45:08 +0000,Jens.Toerring写道:
[snip]
On Tue, 31 May 2005 17:45:08 +0000, Jens.Toerring wrote: [snip]
[...]要求所有指针类型
都可以转换为void指针[...]
[...] requiring that all pointer types
can be converted to and from a void pointer [...]



难道这不应该是所有_object_指针类型或类似
的东西吗?我得到的是ISTR,你不能将函数指针存储在void指针中。


Isn''t this supposed to be all _object_ pointer types or something like
that? What I am getting at is that ISTR that you cannot store a function
pointer in a void pointer.




你是对的,最后到目前为止据我所知,标准只是对象类型指针和void指针之间的转换
保证可以正常工作。允许在void和func-

tion指针之间进行转换被列为公共扩展名,因此它不是

便携式。

问候,Jens

-

\ Jens Thoms Toerring ___ Je *********** @ physik.fu-berlin.de

\ __________________________ http://www.toerring.de


这篇关于一些指针再次停顿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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