【发布时间】:2016-08-02 15:24:04
【问题描述】:
问题:
如果我有两个用restrict 限定的指针(基本上是begin 和end)。 begin 指针用于解除引用/读取,end 指针是一个过去的指针,它永远不会被解除引用,仅用于检查范围的大小(通过end - begin)。一旦使用了范围,我希望 begin 和 end 相等,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和size,只需要修改data:
#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 对指针的限制,这是否允许?
【问题讨论】:
-
@LPs:我的问题不同。我不想通过别名指针访问同一个对象。
end指针永远不会被取消引用,并且唯一一次data和end别名是当它们相等时(此时取消引用无论如何都是未定义的行为)。我的问题是关于比较两个指针,这是不同的。 -
显示到建议的副本中,只要您不修改指向的对象,就会定义行为。可能我错过了什么......
-
注意
.end = argv[1] + (argv[1] ? strlen(argv[1]) : 0)是奇怪的。我期待.end = (argv[1] ? argv[1] + strlen(argv[1]) : argv[1])。您的代码引发了“将 0 添加到NULL是否可以”的问题(可能是一个很好的 SO 问题)。建议避免。