受限指针问题 [英] Restricted pointer questions

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

问题描述

我有点困惑关于限制指针的规则。也许有人在那里可以帮助我。


  1. 是否合法界定嵌套受限指针如下:

     为int *限制一个;
    为int *限制B:
    A =的malloc(sizeof的(INT));
    // B = A; < - 分配这里是非法的,需要孩子块发生
    // * B = RAND();
    而(1)
    {
        B = A; //这是合法的吗?假设B不修改,而在外面()块
        * B = RAND();
    }


  2. 是合法的得到一个受限制的指针值如下:

     为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.

  1. 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();
    }
    

  2. 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 to b, even inside a "child" block - the result is undefined. Such an assignment could be made if b were declared in that 'sub-block', but since b is declared at the same scope as a, the assignment cannot be made.

For question 2, the assignments between c and d 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屋!

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