限制成员函数的限定符(限制这个指针)

注意:为了澄清,这个问题不是关于通常使用restrict关键字,而是关于将其应用于成员函数的具体描述。

GCC允许您使用的__restrict__ (GNU的++相当于C99的restrict )限定符上的成员函数,有效地使this一限制的功能的范围内合格指针。 牛肉在哪里?

大多数成员函数上的其他成员的工作,通过访问它们this ,这是一个T* const (和通常非混淆)。 对于this可能是别名,需要在成员函数中使用第二个指向类型的指针,并且它必须来自某个地方。
对于非成员函数来说,情况通常是这种情况,例如所有二元运算符或任何其他至少需要两个指针或引用相同的非平凡类型的自由函数。 但是,这些函数没有this ,所以它们不相关。

赋值运算符,拷贝构造函数和一元比较运算符是成员函数的示例,原则上this可能是别名(因为另一个对象是通过引用传递的)。 因此,为这些分配一个限制限定符才有意义 - 编译器应该已经很清楚所有其他函数都具有restrict属性(因为从来没有第二个指针指向T)。

现在,例如,如果你对operator=使用restrict ,那么你应该根本不检查自赋值,因为你说this不是在该函数范围内的别名(如果这是真的,那么不能自我赋值可能发生)。
显然,这是你事先不可能知道的东西,也是没有道理的。

那么,如果真的想给成员函数一个限制限定符并且它有意义的话,会是什么情况呢?


要么我错过了一些东西,要么你的问题没有道理。 this与成员函数的任何其他参数没有什么不同,那么为什么你感到惊讶,GCC允许你对它应用restrict

关于将其应用于赋值运算符,您正确地指出,它将避免需要进行明确的自分配测试。 然后你说:

显然,这是你事先不可能知道的事情

但是当你对任何东西使用restrict时,总是这样。 例如,有人可能决定调用memcpy与重叠的内存区域; 你“不可能事先知道”他们不会这样做。 但是对于memcpy参数的restrict声明意味着如果他们这样做了,就会犯下错误。 以完全相同的方式,如果您声明了赋值运算符restrict ,那么您为某人自行分配该类的对象造成了错误。 这一点根本没有什么神秘或矛盾的; 它只是restrict语义的一部分,它对代码的其余部分施加了一定的限制。

我也不确定为什么你发现成员函数不可能将指针(或引用)指向另一个相同类型的对象。 简单的例子:

class Point {
public:
    double distance(const Point &other) const;
};

这种事情总是会出现。

所以真正的问题是,你为什么认为this与其他任何争论是如此不同? 或者,如果你愿意,我怎么完全错过了你的观点?


我相信了你们缺少的是一个参数传递给一个成员函数可能还别名零件或物体。 这是一个例子

struct some_class {
    int some_value;

    void compute_something(int& result) {
        result = 2*some_value;
        ...
        result -= some_value;
    }
}

人们可能会期望编译

*(this + offsetof(some_value)) -> register1
2*register1 -> register2
...
register2 - register1 -> result

不幸的是,如果有人将结果的引用传递给some_value,那么该代码就会出错 。 因此,编译器实际上需要生成以下内容

*(this + offsetof(some_value)) -> register1
2*register1 -> register2
register2 -> result

...
*(this + offsetof(some_value)) -> register1
result -> register2
register2 - register1 -> register2
register2 -> result

这显然效率较低。 请注意,除非compute_something是内联的,否则编译器无法知道结果是否可能是some_value的别名,所以它不得不假设最坏的情况,不管它是否聪明或愚蠢。 所以即使应用于这个指针,也有一个确定的,非常真实的限制优势。


你发布的链接很有趣。 restrict适用this不会有坚实的用例。 正如你在你的问题中提到的,复制构造函数operator =可能是潜在的候选者; 但编译器可以照顾他们。

但以下情况可能会很有趣

struct A
{
  //...
  void Destroy (A*& p) __restrict__
  {
    delete this;
    p = 0;
    p++;
  }
};

现在用例可以;

A **pp = new A*[10];
for(int i = 0; i < 10; i++)
  pp[i] = new A;
//...
A* p = pp[0];
for(int i = 0; i < 10; i++)
  p->Destroy(p);
delete[] pp;

虽然这是非常不寻常的做法,但这是我能想到的唯一案例。

链接地址: http://www.djcxy.com/p/64045.html

上一篇: restrict qualifier on member functions (restrict this pointer)

下一篇: Rules for using the restrict keyword in C?