使用纯属性注释const成员函数

Bar*_*rry 15 c++ gcc

状态的gcc文档__attribute__((pure)):

除返回值外,许多函数都没有效果,它们的返回值仅取决于参数和/或全局变量.这样的函数可以像算术运算符那样经受公共子表达式消除和循环优化.应使用属性声明这些函数pure.

仅依赖于参数意味着什么?考虑:

struct Wrapper {
    int i;

    int get() const { return i; }
    void set(int x) { i = x; }
};
Run Code Online (Sandbox Code Playgroud)

标记Wrapper::get()pure成员函数是否有效?它只取决于隐式Wrapper实例,但数据可能会改变.

Leo*_*eon 6

标记Wrapper::get()pure成员函数是否有效?它仅取决于隐式Wrapper实例,但该数据可能会更改。

是的,Wrapper::get()满足gcc的pure属性要求。但是请注意,这__attribute__((pure))并不意味着学术意义上的纯粹,即拥有引用透明的属性。后者可以通过更严格的__attribute__((const)):

__attribute__((const))

许多函数除了它们的参数之外不检查任何值,并且除了返回值之外没有任何影响。基本上这只是比pure下面的属性稍微更严格的类,因为不允许函数读取全局内存。

请注意,不得声明具有指针参数并检查指向的数据的函数const。同样,调用非const函数的函数通常不能是const. const函数返回没有意义void

但由于Wrapper::get()不具备 所隐含的参照透明性__attribute__((const)),因此不能被贴上标签。

编辑

关于pure函数的-ness(在 gcc 的意义上)的保证可用于仅优化不包含对全局内存的写入的代码块(尤其是不会被对非pure函数的调用穿插)。例子:

struct Wrapper {
    int i;

    int get() const __attribute__((pure)) { return i; }
    void set(int x) { i = x; }
};

long foo(Wrapper* w)
{
    // w->get() can be computed once
    return 2 * w->get() * w->get();
}

long bar(Wrapper* w)
{
    // w->get() can be computed once (even though below code writes to memory,
    // that memory is freshly allocated and cannot be accessed by w->get())
    long result = 2;
    result *= w->get();
    result *= w->get();
    return result;
}

long baz(Wrapper* w)
{
    // both w->get()s must be evaluated, since non-pure code occurs between them
    long result = 2;
    result *= w->get();
    std::cout << "Result after the first muliplication: " << result << std::endl;
    result *= w->get();
    return result;
}
Run Code Online (Sandbox Code Playgroud)

  • 您确定“__attribute__((const))”吗?隐式的“this”不是函数的指针参数吗? (2认同)