2016-08-02 36 views
1

问:

如果我有两个指针(本质上是一个beginend),它有资格与restrict。指针begin用于解引用/读取,而指针end是一个永远不会被解除引用的单指针指针,仅用于检查范围的大小(通过end - begin)。一旦范围被消耗,我预计beginend是相等的,并且end - begin为0,尽管此时两个指针永远不会被解除引用。我可以减去或比较受限制的指针吗?

鉴于restrict对指针的限制,是否定义明确的行为来减去并比较这两个指针?

MVCE:

我有这样一些代码如下:

#include <stddef.h> 

struct Reader { 
    const char* restrict data; 
    size_t size; 
}; 

char read_char(struct Reader* reader) { 
    --reader->size; 
    return *reader->data++; 
} 

int main(int argc, char* argv[]) { 
    struct Reader reader = { 
    .data = argv[1], 
    .size = argv[1] ? strlen(argv[1]) : 0, 
    }; 

    if (reader.size > 0) { 
    return read_char(&reader); 
    } 
    return 0; 
} 

我想改变它,以便而不必阅读时,只data需要修改这两个datasize的被修改:

#include <stddef.h> 

struct Reader { 
    const char* restrict data; 
    const char* restrict end; // Not sure if this should be restrict or not. 
}; 

char read_char(struct Reader* reader) { 
    return *reader->data++; 
} 

int main(int argc, char* argv[]) { 
    struct Reader reader = { 
    .data = argv[1], 
    .end = argv[1] + (argv[1] ? strlen(argv[1]) : 0), 
    }; 

    if (reader.end - reader.data > 0) { // Is this okay? 
    return read_char(&reader); 
    } 
    return 0; 
} 

这是允许的,因为restrict对指针的限制?

+0

可能重复[在某些情况下可以使用限制指针访问同一对象吗?](http://stackoverflow.com/questions/18059205/can-you-use-restrict-ed-pointers-to - 在某些情况下访问相同的对象) – LPs

+0

@LPs:我的问题不同。我不想通过别名指针访问同一个对象。 'end'指针永远不会被取消引用,并且唯一的时候'data'和'end'别名是相等的(在这一点上,取消引用或者是不确定的行为)。我的问题是关于比较两个不同的指针。 – Cornstalks

+0

进入建议的副本显示,只要您不修改指出的对象的行为被定义。可能我错过了一些东西...... – LPs

回答

5

TL; DR:我的阅读标准允许您使用。

使用restrict限定指针的标准要求都与混叠和访问指向对象有关。我发现使用这样的指针作为指针差异运算符(-)的操作数没有限制,并且这种限制与restrict(这将提供更多的优化机会)的目的不一致。

相比之下,通过添加整数从restrict合格的指针获得的指针值是“基于”原始指针的,这对于标准是重要的。粗略地说,通过这样一个指针访问指向对象是可以接受的,而通过指向不是“基于”受限指针的相同对象的指针来访问该对象是不可接受的。

此外,我不认为Reader.end需要restrict -qualified,我不认为这样的资格可以帮助你。但是,您必须确保Reader.end和从它派生的任何指针都不用于访问数据;你只能使用Reader.data。也在main()。另一方面,如果你无处修改所指向的对象,那么几乎所有这些都没有意义。