受限指针问题 [英] Restricted pointer questions
问题描述
我有点困惑关于限制指针的规则。也许有人在那里可以帮助我。
-
是否合法界定嵌套受限指针如下:
为int *限制一个;
为int *限制B:
A =的malloc(sizeof的(INT));
// B = A; < - 分配这里是非法的,需要孩子块发生
// * B = RAND();
而(1)
{
B = A; //这是合法的吗?假设B不修改,而在外面()块
* B = RAND();
} -
是合法的得到一个受限制的指针值如下:
为int *限制℃;
为int *限制D组;
C =的malloc(sizeof的为(int *)* 101);
D = C:
的for(int i = 0; I< 100;我++)
{
* D = 1;
ð++;
}
C = D组; // C现在设置为101元,这是假设合法D不访问?
* C = RAND();
谢谢!
安德鲁
有关参考,这里的限制
预选赛的颇为曲折的定义(从C99 6.7.3.1的正式定义限制):
D是一个普通的声明
标识符提供一种手段
指定一目标P作为
限制限定指针类型T
若D出现块内,
没有存储类
EXTERN,令B表示块。若D
出现在参数列表
一个函数的声明
定义,令B表示
相关的块。否则,令B
指的主要块(或块
任何的函数被调用时
在一个独立的程序启动
环境)。
在下文中,一个指针
前pression E被说成是基于
物P如果(在某些序列点
以B之前执行
电子商务评估)修改P至点
到数组对象的副本进入
其前身是指将改变
,基于大肠注值
只为与前pressions定义
指针类型。
在的B每次执行,令L为
具有与放大器的左值; l基于P.如果
L用于访问的价值
对象X,它表示,且X是
还修改(通过任何方式),那么
需要满足以下要求:T已应
不能为const修饰。所有其他
左值用于访问X的值
还应当有基于它的地址
P.一个修改点¯x每款的访问
可也算修改P,为
本节的目的。若P
被分配一个指针的值
这是基于另一位前pressionË
受限制的指针对象P2,
与块B2关联,则无论是
B2前应开始执行
B的执行,或者
B2的执行应结束之前
分配。如果这些
要求得不到满足,那么
行为是不确定的。
下面B的执行指
的执行部分
程序,将对应于
标量类型的对象寿命
并自动存储时间
与B相关联。
块引用>我上面的读取装置,在你的第一个问题,
A
不能分配给B
,甚至里面子块 - 结果是不确定的。这样的分配可以如进行b
在分块被宣布,但由于B
声明在在相同的范围为A
,分配无法进行。有关问题2,之间
C
和D
的分配也导致不确定的行为(在这两种情况下)。从标准(这两个问题)的相关位是:
如果P被分配的值
这是基于指针的前pressionË
另一个限制指针对象P2,
与块B2关联,则无论是
B2前应开始执行
B的执行,或者
B2的执行应结束之前
分配。
块引用>由于受限指针与同块相关,这是不可能的块B2到B的执行之前开始,或B2之前的分配(因为B和B2是相同的块)结束。
该标准给出了使这个pretty清楚(我想一个例子 - 的清晰度
限制
定义的4小段是用C ++的名字解析规则看齐):
实施例4:
该规则限制之间的分配
受限指针不
一个函数调用区分
和等效嵌套块。
有一个例外,只
与外到内的任务
嵌套宣布受限指针
块定义的行为。{
为int *限制P1;
为int *限制Q1; P1 = Q1; //未定义行为 {
为int *限制P2 = P1; //有效
为int *限制Q2 = Q1; //有效
P1 = Q2; //未定义行为
P2 = Q2; //未定义行为
}
}
块引用>I'm a little confused about the rules regarding restricted pointers. Maybe someone out there can help me out.
Is it legal to define nested restricted pointers as follows:
int* restrict a; int* restrict b; a = malloc(sizeof(int)); // b = a; <-- assignment here is illegal, needs to happen in child block // *b = rand(); while(1) { b = a; // Is this legal? Assuming 'b' is not modified outside the while() block *b = rand(); }
Is it legal to derive a restricted pointer value as follows:
int* restrict c; int* restrict d; c = malloc(sizeof(int*)*101); d = c; for(int i = 0; i < 100; i++) { *d = i; d++; } c = d; // c is now set to the 101 element, is this legal assuming d isn't accessed? *c = rand();
Thanks! Andrew
解决方案For reference, here's the
restrict
qualifier's rather convoluted definition (from C99 6.7.3.1 "Formal definition of restrict"):Let D be a declaration of an ordinary identifier that provides a means of designating an object P as a restrict-qualified pointer to type T.
If D appears inside a block and does not have storage class extern, let B denote the block. If D appears in the list of parameter declarations of a function definition, let B denote the associated block. Otherwise, let B denote the block of main (or the block of whatever function is called at program startup in a freestanding environment).
In what follows, a pointer expression E is said to be based on object P if (at some sequence point in the execution of B prior to the evaluation of E) modifying P to point to a copy of the array object into which it formerly pointed would change the value of E. Note that "based" is defined only for expressions with pointer types.
During each execution of B, let L be any lvalue that has &L based on P. If L is used to access the value of the object X that it designates, and X is also modified (by any means), then the following requirements apply: T shall not be const-qualified. Every other lvalue used to access the value of X shall also have its address based on P. Every access that modifies X shall be considered also to modify P, for the purposes of this subclause. If P is assigned the value of a pointer expression E that is based on another restricted pointer object P2, associated with block B2, then either the execution of B2 shall begin before the execution of B, or the execution of B2 shall end prior to the assignment. If these requirements are not met, then the behavior is undefined.
Here an execution of B means that portion of the execution of the program that would correspond to the lifetime of an object with scalar type and automatic storage duration associated with B.
My reading of the above means that in your first question,
a
cannot be assigned tob
, even inside a "child" block - the result is undefined. Such an assignment could be made ifb
were declared in that 'sub-block', but sinceb
is declared at the same scope asa
, the assignment cannot be made.For question 2, the assignments between
c
andd
also result in undefined behavior (in both cases).The relevant bit from the standard (for both questions) is:
If P is assigned the value of a pointer expression E that is based on another restricted pointer object P2, associated with block B2, then either the execution of B2 shall begin before the execution of B, or the execution of B2 shall end prior to the assignment.
Since the restricted pointers are associated with the same block, it's not possible for block B2 to begin before the execution of B, or for B2 to end prior to the assignment (since B and B2 are the same block).
The standard gives an example that makes this pretty clear (I think - the clarity of the
restrict
definition's 4 short paragraphs is on par with C++'s name resolution rules):EXAMPLE 4:
The rule limiting assignments between restricted pointers does not distinguish between a function call and an equivalent nested block. With one exception, only "outer-to-inner" assignments between restricted pointers declared in nested blocks have defined behavior.
{ int * restrict p1; int * restrict q1; p1 = q1; // undefined behavior { int * restrict p2 = p1; // valid int * restrict q2 = q1; // valid p1 = q2; // undefined behavior p2 = q2; // undefined behavior } }
这篇关于受限指针问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!