用普通英语'限制'? [英] 'restrict' in plain English?

查看:82
本文介绍了用普通英语'限制'?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图围绕措辞,但我认为

标准说:


1.它是不可能将限制指针与另一个指针交换,




int a = 1,b = 2;

int *限制ap =& a;

int * restrict bp =& b;


int * temp = bp;

bp = ap;

ap = bp;


未定义。


2.它不会支持完全重叠的内存,即


void v3add(浮动*限制a,浮动*限制b)

{

a [0 ] + = b [0];

a [1] + = b [1];

a [2] + = b [2];

}


浮动a [] = {1,2,3};

v3add(a,a);


未定义。


3.库更改可能会破坏(正确?)现有代码,即


FILE * fopen (const char * restrict filename,const char * restrict

mode);


FILE * f = fopen(&q uot; foo.rt"," rt");


如果编译器将其转换为:


static const char str [] =" foo.rt";

FILE * f = fopen(str,str + 4);


代码未定义。


这是否正确?

解决方案

2006年3月5日17:30:37 -0800 ,我 < a ***************** @ yahoo.com>

在comp.lang.c中写道:

我正试图围绕措辞,但我认为
标准说:

1.将限制指针与另一个指针交换是不可能的指针,

int a = 1,b = 2;
int * restrict ap =& a;
int * restrict bp =& b;

int * temp = bp;


我相信这需要演员。

bp = ap;
ap = bp;

是未定义。


为什么你认为这是未定义的?它可能是,取决于你用指针做什么


2.它不支持完全重叠的内存,即

void v3add(float * restrict a,float * restrict b)
{
a [0] + = b [0];
a [1] + = b [1];
a [2] + = b [2];
}
浮动a [] = {1,2,3};
v3add(a,a);


函数本身定义良好,对函数的调用是假设,技术上未定义。虽然这个实际使用没有问题



未定义。

3.库更改可能会破坏(正确吗?)现有代码,即

FILE * fopen(const char * restrict filename,const char * restrict
模式);

FILE * f = fopen(" foo.rt" ;,rt);

如果编译器将其转换为:

static const char str [] =" foo.rt";
FILE * f = fopen(str,str + 4);

代码变得未定义。


不,上面的代码定义明确。事实上,

编译器本身可能会生成此代码,因为合并字符串文字

是标准允许的,而且有些编译器会这样做。

这是否正确?




限制限定符仅对修改

对象有意义。这就是为什么你的第三个

例子没有任何问题。传递给fopen()的两个字符串是const限定的,并且

函数不会尝试修改它们。


你的第二个例子并不是真的未定义因为甚至虽然

修改''a'指向的对象也修改了'b''指向

的对象,但是没有使用任何指向的对象的值通过a来修改后,通过''b''




考虑第二个例子的这个版本: br />

void v3add(浮动*限制a,浮动*限制b)

{

a [0] + = b [0] ; / * a [0] = b [0] = 2 * /

a [1] + = b [0]; / * a [1] = 2 + 2 = 3 * /

a [2] + = b [0]; / * a [1] =

}


int main()

{

浮动a [] = {1,2,3};

v3add(a,a);

/ * printf()'a''* *的值

返回0;

}


如果没有上面的''restrict''关键字,编译器就不能认为

''''和'b''点不指向同一区域。具体来说,他们

不能假设b [0]没有被任何任务改变

到'a''。使用''restrict''关键字,它可以假设,并根据该假设生成

代码。代码很可能只需要b $ 0实际读取b [0]一次。


restrict类型限定符的概念是通知编译器

特定指针指向的对象不会通过该指针修改
,或者从

派生的指针考虑:


const int ci = 12;


void some_func(void )

{

some_global_function();

if(ci == 12)

{

printf(是的,它仍然是12 \ n);

}

}


....和:


void other_func(int restrict * ip)

{

* ip = 12;

some_global_function();

if(* ip == 12)

{

printf(" Yep) ,它仍然是12 \ nn);

}

}


在上述两种情况下,编译器有理由省略测试

和制作printf()调用无条件。


这首先是正确的,因为它取决于

const对象的值保持不变。 />

在第二种情况下,这是真的,因为你已经答应了

编译器,当你告诉它它的参数是限制合格时,

绝对没有任何事情发生在程序中将修改ip

指向的内容而不通过ip进行操作。


这允许某些无法实现的优化

否则,即编译器不必执行测试if

(* ip == 12)。您已经向编译器承诺,在调用some_global_func()期间发生的任何事情都不会被修改。

ip指向的对象将不会被修改。


如果限制限定指针指向的对象是const,

或者只是在

限制合格的指针,它们的关键字根本没有意义。


这是关于告诉编译器何时可以假设

指向对象不会在不知情的情况下更改。


-

Jack Klein

主页: http://JK-Technology.Com



comp.lang.c http://c-faq.com/

comp.lang.c ++ http:/ /www.parashift.com/c++-faq-lite/

alt.comp.lang.learn.c-c ++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html




Jack Klein写道:

2006年3月5日17:30:37 -0800,我 < a ***************** @ yahoo.com>
在comp.lang.c中写道:

I我试图围绕措辞,但我认为
标准说:

1.将限制指针与另一个指针交换是不可能的。 /> ie

int a = 1,b = 2;
int * restrict ap =& a;
int * restrict bp =& b;

int * temp = bp;



这应该需要演员,我相信。




你也是认为我下面的设置需要演员吗?


const int ci = 1;

int i = ci;


如果没有,你能解释两个例子在类型限定词方面的差异吗?


en ****** @ yahoo.com 写道:

Jack Klein写道:

2006年3月5日17:30:37 -0800,Me < an ***************** @ yahoo.com>
在comp.lang.c中写道:

我正试图围绕措辞,但我认为
标准说:

1。将限制指针与另一个指针交换是不可能的,即

int a = 1,b = 2;
int * restrict ap =& a;
int * restrict bp =& b;

int * temp = bp;



我相信这应该需要演员。



你是否认为下面我的设置需要演员?

const int ci = 1;
int i = ci;
<如果没有,你能解释两个例子在类型限定词方面的区别吗?



不,这是一个直接的任务。你没做什么我可以改变ci。

而将const指针指向非const则违反了

限制,因为你可以改变指针指向的值。 br />

-

Ian Collins。


I''m trying to wrap my head around the wording but from what I think the
standard says:

1. it''s impossible to swap a restrict pointer with another pointer,
i.e.

int a = 1, b = 2;
int * restrict ap = &a;
int * restrict bp = &b;

int *temp = bp;
bp = ap;
ap = bp;

is undefined.

2. it doesn''t support exactly overlapping memory, i.e.

void v3add(float * restrict a, float * restrict b)
{
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
}

float a[] = { 1, 2, 3 };
v3add(a, a);

is undefined.

3. the library changes may break (correct?) existing code, i.e.

FILE *fopen(const char * restrict filename, const char * restrict
mode);

FILE *f = fopen("foo.rt", "rt");

if the compiler transforms this to:

static const char str[] = "foo.rt";
FILE *f = fopen(str, str + 4);

the code becomes undefined.

Is any of this correct?

解决方案

On 5 Mar 2006 17:30:37 -0800, "Me" <an*****************@yahoo.com>
wrote in comp.lang.c:

I''m trying to wrap my head around the wording but from what I think the
standard says:

1. it''s impossible to swap a restrict pointer with another pointer,
i.e.

int a = 1, b = 2;
int * restrict ap = &a;
int * restrict bp = &b;

int *temp = bp;
This should require a cast, I believe.
bp = ap;
ap = bp;

is undefined.
Why do you think this is undefined? It might be, depending on what
you do with the pointers.
2. it doesn''t support exactly overlapping memory, i.e.

void v3add(float * restrict a, float * restrict b)
{
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
}

float a[] = { 1, 2, 3 };
v3add(a, a);
The function itself is well defined, the call to the function is, I
suppose, technically undefined. Although there is no problem with
this actual use.
is undefined.

3. the library changes may break (correct?) existing code, i.e.

FILE *fopen(const char * restrict filename, const char * restrict
mode);

FILE *f = fopen("foo.rt", "rt");

if the compiler transforms this to:

static const char str[] = "foo.rt";
FILE *f = fopen(str, str + 4);

the code becomes undefined.
No, the code above is well-defined. In fact, it is possible that a
compiler might generate this code itself, as merging string literals
is allowed by the standard and some compilers do it.
Is any of this correct?



The restrict qualifier only has meaning in terms of modifying an
object. That''s why there is no problem at all with your third
example. The two strings passed to fopen() are const qualified and
the function does not try to modify them.

Your second example is not really undefined because even though
modifying objects pointed to by ''a'' also modifies objects pointed to
by ''b'', there is no use of the value of any object pointed to by ''b''
after it is modified by the write through ''a''.

Consider this version of your second example:

void v3add(float * restrict a, float * restrict b)
{
a[0] += b[0]; /* a[0] = b[0] = 2 */
a[1] += b[0]; /* a[1] = 2 + 2 = 3 */
a[2] += b[0]; /* a[1] =
}

int main()
{
float a[] = { 1, 2, 3 };
v3add(a, a);
/* printf() the values of ''a'' */
return 0;
}

Without the ''restrict'' keyword above, the compiler cannot assume that
''a'' and ''b'' point do not point to the same area. Specifically, they
can''t assume that b[0] is not changed by any of the assignments
through ''a''. With the ''restrict'' keyword it can assume, and generate
code based on that assumption. It is quite likely that the code will
actually read b[0] only once.

The concept of the restrict type qualifier is to inform the compiler
that the object(s) pointed to by a particular pointer will not be
modified other than through that pointer, or a pointer derived from
it.

Consider:

const int ci = 12;

void some_func(void)
{
some_global_function();
if (ci == 12)
{
printf("Yep, it''s still 12\n");
}
}

....and:

void other_func(int restrict *ip)
{
*ip = 12;
some_global_function();
if (*ip == 12)
{
printf("Yep, it''s still 12\n");
}
}

In both cases above, the compiler is justified in omitting the test
and making the printf() call unconditional.

This is true in the first place because it depends on the value of a
const object remaining the same.

In the second case, this is true because you have promised the
compiler, when you tell it its argument is restrict qualified, that
absolutely nothing that happens in the program will modify what ip
points to without doing so through ip.

This allows certain optimizations that would not be possible
otherwise, namely the compiler does not have to perform the test "if
(*ip == 12)". You have promised the compiler that whatever happens
during the call to "some_global_func()", the object(s) pointed to by
ip will not be modified.

If the object(s) pointed to by restrict qualified pointers are const,
or merely nothing attempts to modify them during the scope of a
restrict qualified pointer, they keyword has no meaning at all.

It is all about telling the compiler when it can assume that the
pointed to object(s) will not be changed without its knowledge.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html



Jack Klein wrote:

On 5 Mar 2006 17:30:37 -0800, "Me" <an*****************@yahoo.com>
wrote in comp.lang.c:

I''m trying to wrap my head around the wording but from what I think the
standard says:

1. it''s impossible to swap a restrict pointer with another pointer,
i.e.

int a = 1, b = 2;
int * restrict ap = &a;
int * restrict bp = &b;

int *temp = bp;



This should require a cast, I believe.



Do you also think the setting of i below requires a cast?

const int ci = 1;
int i = ci;

If not, can you explain how the two examples differ
with regard to type qualifiers?


en******@yahoo.com wrote:

Jack Klein wrote:

On 5 Mar 2006 17:30:37 -0800, "Me" <an*****************@yahoo.com>
wrote in comp.lang.c:

I''m trying to wrap my head around the wording but from what I think the
standard says:

1. it''s impossible to swap a restrict pointer with another pointer,
i.e.

int a = 1, b = 2;
int * restrict ap = &a;
int * restrict bp = &b;

int *temp = bp;



This should require a cast, I believe.


Do you also think the setting of i below requires a cast?

const int ci = 1;
int i = ci;

If not, can you explain how the two examples differ
with regard to type qualifiers?


No it''s a straight assignment. Nothing you do with i can change ci.
whereas assigning a const pointer to a non-const violates the
restriction because you can alter the value the pointer points to.

--
Ian Collins.


这篇关于用普通英语'限制'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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