以下代码可以吗? [英] Is the following code OK?

查看:91
本文介绍了以下代码可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我必须将结构地址与绝对地址进行比较(这个

地址表示内存组件的开始)。

现在我的问题是以下代码leagal: -


#include< stdio.h>


int main()

{

struct t {

int a;

int b;

} b; b struct t * ptr =& temp;


if(ptr< 0x120000)

printf(What\ n);

else

printf(" hell \ nn);

返回0 ;

}


我关心的是if语句中的比较,因为正在比较结构

指针和unsigned int 。在任何情况下都可以有一个

未定义的行为吗?

hi all,
I have to compare an address of structure with an absolute address(this
address signifies the start of a memory component).
Now my question is the follwong code leagal:-

#include <stdio.h>

int main()
{
struct t{
int a;
int b;
}temp;

struct t* ptr=&temp;

if(ptr<0x120000)
printf("What\n");
else
printf("The hell\n");
return 0;
}

My concern is the comparision in the if statement because a structure
pointer and an unsigned int are being compared. Can there be an
undefined behaviour in any cases ?

推荐答案


vb@gmail.com 写道:
大家好,
我必须将结构地址与绝对地址进行比较(这个
地址表示内存组件的开始。)
现在我的问题是以下代码leagal: -

#include< stdio.h>

int main()
{
int t;
int b;
} temp;

struct t * ptr =& temp;

if(ptr< 0x120000)
hi all,
I have to compare an address of structure with an absolute address(this
address signifies the start of a memory component).
Now my question is the follwong code leagal:-

#include <stdio.h>

int main()
{
struct t{
int a;
int b;
}temp;

struct t* ptr=&temp;

if(ptr<0x120000)



< snip>


以上比较需要整数到指针转换,其中
是特定于实现的。


<snip>

The above comparison requires integer to pointer conversion, which
is implementation specific.


vb@gmail.com 写道:
大家好,
我必须比较一个绝对的结构地址地址(这个
地址表示内存组件的开始)。
现在我的问题是以下代码leagal: -

#include< stdio.h>

int main()
{
int t {
int;
int b;
} temp;

struct t * ptr =& temp;

if(ptr< 0x120000)
printf(What\ n);

printf(" ; hell \\\
;
返回0;
}

我关心的是if语句中的比较因为结构
指针和unsigned int被比较。在任何情况下都可能存在未定义的行为吗?


比较中有(至少)两个错误,

一个误解。误解首先:0x120000

可能不是unsigned int。 "大概"因为是

由编译器为每个

字面常量选择合适的类型,不同的编译器使用不同的位

计数为各种整数类型。 0x120000

的类型将是{int,unsigned int,long,unsigned long,

long long,unsigned long long}中的第一个,它可以表示其值,

,在大多数系统中,这将是int或

long。据我所知,0x120000只能在21位整数的机器上使用unsigned int




除了迂腐的离题外,还有实质性问题。

首先,正如你所怀疑的那样,除了
的特殊情况之外,不可能将指针

与任何整数风格进行比较。
整数常量零(表示空指针)。指针

不是数字;数字不是指针。你正试图用b $ b比较苹果和猩猩。


您可以尝试通过将

整数转换为a来挽救这种情况写入指针(struct t *)0x120000,但这个

并没有真正解决任何问题,即使它可能导致

编译器停止抱怨。第一个难点是

即使转换运算符可以将整数转换为指针

(反之亦然),转换的结果是实现 -

已定义且无需有意义。特别是,它不需要
产生有效的,可用的结果。如果你愿意的话,你可以宣布一只猩猩转换成十二个半月的苹果,然后再说你已经比较了它们,但是这样的反复无常

有用:苹果和猩猩都不会对这些荒谬的声明给予任何关注

。他们不同的开始了,并且尽管愚蠢的唠叨,他们仍然不同。


也就是说,许多机器*做*提供有用的转换
指针和至少一种整数之间的
,所以即使这个C语言并不需要任何有意义的东西你也可以得到

无论如何。但是你仍然没有走出困境!

转换可能会产生一个有效的指针,但它可能不是
是一个有效的`struct t *''指针 - 例如,它可能不是
满足'struct t''对象的对齐要求。


嗯,有17个低阶整数中的零位

你正在使用,所以不对中的可能性很小...... b $ b小。我们安全吗?好吧,不。 (你期待什么?;-)

下一个问题是关系运算符<,< =,=,>只能应用于指定位置的指针
hi all,
I have to compare an address of structure with an absolute address(this
address signifies the start of a memory component).
Now my question is the follwong code leagal:-

#include <stdio.h>

int main()
{
struct t{
int a;
int b;
}temp;

struct t* ptr=&temp;

if(ptr<0x120000)
printf("What\n");
else
printf("The hell\n");
return 0;
}

My concern is the comparision in the if statement because a structure
pointer and an unsigned int are being compared. Can there be an
undefined behaviour in any cases ?
There are (at least) two errors in the comparison, and
one misunderstanding. The misunderstanding first: 0x120000
is probably not an unsigned int. "Probably" because is is
up to the compiler to choose an appropriate type for each
literal constant, and different compilers use different bit
counts for the various integer types. The type of 0x120000
will be the first of { int, unsigned int, long, unsigned long,
long long, unsigned long long } that can represent its value,
and on most systems this will turn out to be either int or
long. As far as I can see, 0x120000 could be an unsigned int
only on a machine with 21-bit integers.

Pedantic digressions aside, on to the substantive problems.
First, as you suspect, it is not possible to compare a pointer
to any flavor of integer, except for the special case of an
integer constant zero (which signifies a null pointer). Pointers
are not numbers; numbers are not pointers. You are trying to
compare apples and orangutans.

You could try to rescue the situation by converting the
integer to a pointer by writing (struct t*)0x120000, but this
doesn''t really solve anything even though it may cause the
compiler to stop complaining. The first difficulty is that
even though a cast operator can convert an integer to a pointer
(and vice-versa), the result of the conversion is implementation-
defined and need not be meaningful. In particular, it need not
produce a valid, usable result. You can, if you like, declare
that one orangutan converts to twelve and a half apples and then
claim you''ve compared them, but such capriciousness is not very
useful: neither the apple nor the orangutan pays any attention
to such nonsensical declarations. They were different to begin
with, and different they remain despite silly babbling.

That said, many machines *do* provide useful conversions
between pointers and at least one kind of integer, so even if
the C language doesn''t require anything meaningful you may get
some meaning anyhow. But you''re still not out of the woods!
The conversion may produce a valid pointer, but it might not
be a valid `struct t*'' pointer -- it might, for example, not
satisfy the alignment requirement for a `struct t'' object.

Well, there are seventeen low-order zero bits in the integer
you''re using, so the likelihood of misalignment is vanishingly
small. Are we safe yet? Well, no. (What did you expect? ;-)

The next problem is that the relational operators <, <=,=, > can only be applied to pointers that designate locations



在同一个数组中(或之后)。那是


char buff1 [100],buff2 [100];

char * p = buff1,* q = buff1 + 20;

if(p< q)... / * okay:两者都指向buff1 * /

q = buff2;

if(p< q) ... / *没有好处:不同的数组* /


在你的代码中,ptr指向对象temp(被认为是/ b
)在这个上下文中的元素数组),但转换后的0x120000甚至
无法保证指向或仅仅是临时后的
。它指出(如果上面的所有内容都按照你的方式)

到一些完全不相关的内存位置,并且比较

会产生完全愚蠢的结果。 (此相同数组

限制适用于关系运算符,但不适用于

相等运算符:您可以使用==和!= on无关指针,

你就是不能确定哪个是更大。)如果你认为

a有关如何定义指针的减法,那么这一切<
可能会开始产生某种意义。


摘要:一旦所需的演员阵容插入

,您的代码可能会有效。我甚至可以说它可能适用于大多数机器上的b $ b。但是你依赖于C语言无法保证的一大堆东西。在这个意义上,代码是

既不是leagal,也不是leagal。也不合法。尽管如此,这些代码可能是必要的;

某些任务,如系统特定的内存管理,超出了完全便携式C的

功能。


-

Eric Sosman
es ***** @ acm- dot-org.inva lid


in (or just after) the same array. That is

char buff1[100], buff2[100];
char *p = buff1, *q = buff1 + 20;
if (p < q) ... /* okay: both point into buff1 */
q = buff2;
if (p < q) ... /* no good: different arrays */

In your code, ptr points to the object temp (which is thought
of as a one-element array in this context), but 0x120000 even
after conversion is by no means guaranteed to point at or just
after temp. It points (if everything above has gone your way)
to some completely unrelated memory location, and the comparison
can produce completely silly results. (This "same array"
restriction applies to the relational operators but not to the
equality operators: you can use == and != on "unrelated" pointers,
you just can''t establish which is "greater.") If you think for
a bit about how the subtraction of pointers is defined, all this
may begin to make some kind of sense.

Summary: Your code might work, once the required cast is
inserted. I''d go so far as to say it would probably work on
most machines. But you''re relying on a whole slew of things that
are not guaranteed by the C language; in this sense the code is
neither "leagal" nor legal. Such code may be necessary nonetheless;
some tasks like system-specific memory management are beyond the
capabilities of fully portable C.

--
Eric Sosman
es*****@acm-dot-org.invalid


嗨Eric,


感谢您的详细解释。你能澄清我一件事吗?


也可以在同一台机器上进行铸造,结果是确定性的吗?为什么我要求b $ b,指针地址将是虚拟地址,这可能不是
在不同的运行中是相同的。


& temp在堆栈框架上可能没有相同的值?如果正在运行更多进程''

,则可能会发生页面替换,并且相同的值可能无法保证
保证。


问候,

Raju


Eric Sosman写道:
Hi Eric,

Thanks for detailed explaination. Could you clarify me one thing?

Afte casting also, on same machine is the result deterministic? Why I''m
asking is, the pointer address will be virtual address and this may not
be same in different runs.

The &temp may not have same vlaue on the stack frame? If more process''
are running then page replacement can happen and the same value may not
be guarenteed.

Regards,
Raju

Eric Sosman wrote:
vb @ gmail.com 写道:
大家好,
我必须将结构地址与绝对地址进行比较(这个
地址表示内存组件的开始现在我的问题是下面的代码: -

#include< stdio.h>

int main()
{
struct t {
int a;
int b;
} temp;

struct t * ptr =& temp;

if(ptr< 0x120000)
printf(What\ n);

printf(" hell \ nn);
返回0 ;
}

我关心的是if语句中的比较因为结构指针和unsigne正在比较d int。在任何情况下都可能存在未定义的行为吗?
hi all,
I have to compare an address of structure with an absolute address(this
address signifies the start of a memory component).
Now my question is the follwong code leagal:-

#include <stdio.h>

int main()
{
struct t{
int a;
int b;
}temp;

struct t* ptr=&temp;

if(ptr<0x120000)
printf("What\n");
else
printf("The hell\n");
return 0;
}

My concern is the comparision in the if statement because a structure
pointer and an unsigned int are being compared. Can there be an
undefined behaviour in any cases ?



比较中存在(至少)两个错误,以及一个误解。误解首先:0x120000
可能不是unsigned int。 "大概"因为是由编译器为每个
文字常量选择合适的类型,不同的编译器对各种整数类型使用不同的位数。 0x120000的类型将是{int,unsigned int,long,unsigned long,
long long,unsigned long long}中的第一个,它可以代表它的值,
并且在大多数系统上结果将是int或
。据我所知,0x120000只能在21位整数的机器上进行无符号整数。

对于实质性问题,除了迂腐之外。
首先,正如您所怀疑的那样,除了
整数常量零(表示空指针)的特殊情况外,不可能将指针与任何整数风格进行比较。指针
不是数字;数字不是指针。你试图比较苹果和猩猩。

你可以尝试通过写(struct t *)0x120000将
整数转换为指针来挽救这种情况,但是这个
并没有真正解决任何问题,即使它可能导致
编译器停止抱怨。第一个难点是
即使一个强制转换操作符可以将整数转换为一个指针
(反之亦然),转换的结果是实现 -
定义,不需要有意义。特别是,它不需要产生有效的,可用的结果。如果你愿意,你可以宣布一只猩猩转换成十二个半苹果,然后声称你已经比较了它们,但是这种反复无常的有用:不论是苹果和猩猩都对这些荒谬的宣言给予了关注。它们开始时有所不同,尽管愚蠢的唠叨,它们仍然不同。

这就是说,许多机器*做*在指针和至少一种指针之间提供有用的转换。整数,所以即使C语言不需要任何有意义的东西你也可能无论如何都会得到一些意义。但你仍然没有走出困境!
转换可能产生一个有效的指针,但它可能不是一个有效的`struct t *''指针 - 例如,它可能不满足`struct t''对象的对齐要求。

嗯,你正在使用的整数中有17个低阶零位,所以错位的可能性很小。我们安全吗?好吧,不。 (你期待什么?;-)
下一个问题是关系运算符<,< =,



There are (at least) two errors in the comparison, and
one misunderstanding. The misunderstanding first: 0x120000
is probably not an unsigned int. "Probably" because is is
up to the compiler to choose an appropriate type for each
literal constant, and different compilers use different bit
counts for the various integer types. The type of 0x120000
will be the first of { int, unsigned int, long, unsigned long,
long long, unsigned long long } that can represent its value,
and on most systems this will turn out to be either int or
long. As far as I can see, 0x120000 could be an unsigned int
only on a machine with 21-bit integers.

Pedantic digressions aside, on to the substantive problems.
First, as you suspect, it is not possible to compare a pointer
to any flavor of integer, except for the special case of an
integer constant zero (which signifies a null pointer). Pointers
are not numbers; numbers are not pointers. You are trying to
compare apples and orangutans.

You could try to rescue the situation by converting the
integer to a pointer by writing (struct t*)0x120000, but this
doesn''t really solve anything even though it may cause the
compiler to stop complaining. The first difficulty is that
even though a cast operator can convert an integer to a pointer
(and vice-versa), the result of the conversion is implementation-
defined and need not be meaningful. In particular, it need not
produce a valid, usable result. You can, if you like, declare
that one orangutan converts to twelve and a half apples and then
claim you''ve compared them, but such capriciousness is not very
useful: neither the apple nor the orangutan pays any attention
to such nonsensical declarations. They were different to begin
with, and different they remain despite silly babbling.

That said, many machines *do* provide useful conversions
between pointers and at least one kind of integer, so even if
the C language doesn''t require anything meaningful you may get
some meaning anyhow. But you''re still not out of the woods!
The conversion may produce a valid pointer, but it might not
be a valid `struct t*'' pointer -- it might, for example, not
satisfy the alignment requirement for a `struct t'' object.

Well, there are seventeen low-order zero bits in the integer
you''re using, so the likelihood of misalignment is vanishingly
small. Are we safe yet? Well, no. (What did you expect? ;-)

The next problem is that the relational operators <, <=,

> =,>只能应用于在同一个数组中(或之后)指定位置
>=, > can only be applied to pointers that designate locations


的指针。那就是char buff1 [100],buff2 [100];
char * p = buff1,* q = buff1 + 20;
if(p q = buff2;
如果(p 在你的代码中,ptr指向对象temp(在此上下文中被认为是一个单元素数组),但转换后的0x120000甚至不能保证指向或只是
温后。它指出(如果上面的所有内容都按照你的方式)对一些完全不相关的内存位置,并且比较
会产生完全愚蠢的结果。 (此相同数组限制适用于关系运算符,但不适用于
相等运算符:您可以使用==和!= on无关指针,
您可以不要确定哪个是更大。如果你想某些关于如何定义指针的减法,那么这一切可能会开始产生某种意义。

摘要:插入所需的演员表后,您的代码可能会起作用。我甚至可以说它可能适用于大多数机器。但是你依赖于C语言无法保证的一大堆东西;在这个意义上,代码既不是法律,也不是法律。也不合法。尽管如此,这些代码可能是必要的;
某些任务,如系统特定的内存管理,超出了完全可移植的C的能力。

-
Eric Sosman
es*****@acm-dot-org.inva lid


in (or just after) the same array. That is

char buff1[100], buff2[100];
char *p = buff1, *q = buff1 + 20;
if (p < q) ... /* okay: both point into buff1 */
q = buff2;
if (p < q) ... /* no good: different arrays */

In your code, ptr points to the object temp (which is thought
of as a one-element array in this context), but 0x120000 even
after conversion is by no means guaranteed to point at or just
after temp. It points (if everything above has gone your way)
to some completely unrelated memory location, and the comparison
can produce completely silly results. (This "same array"
restriction applies to the relational operators but not to the
equality operators: you can use == and != on "unrelated" pointers,
you just can''t establish which is "greater.") If you think for
a bit about how the subtraction of pointers is defined, all this
may begin to make some kind of sense.

Summary: Your code might work, once the required cast is
inserted. I''d go so far as to say it would probably work on
most machines. But you''re relying on a whole slew of things that
are not guaranteed by the C language; in this sense the code is
neither "leagal" nor legal. Such code may be necessary nonetheless;
some tasks like system-specific memory management are beyond the
capabilities of fully portable C.

--
Eric Sosman
es*****@acm-dot-org.invalid






这篇关于以下代码可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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