有没有办法允许编译器优化多个extern函数调用?

时间:2017-10-15 11:29:26

标签: c++ optimization compile-time

我正在构建一个类似于C库的C ++接口:

extern "C" {

typedef struct CFooStruct *CFoo;

int CFoo_getLength(CFoo);

// other functions

}

目前我有

class MyFoo {
    CFoo foo;
    int len;
public:
    MyFoo(CFoo foo) : foo(foo), len(CFoo_getLength(foo)) { }

    int length() const { return len; } // inline function

    // other functions
};

在构造函数中检索长度并缓存,以便可以在紧密循环中重复调用MyFoo::length()而不会降低性能。

当直接使用C接口时,如果需要,可以手动检索一次的长度,然后重复使用它。如果不需要CFoo的长度,那么我们就永远不会致电CFoo_getLength()

C ++接口意味着更易于使用,让用户只需使用length()而无需考虑性能。上述实现的缺点是,总是在创建每个CFoo_getLength()对象期间调用MyFoo,无论它是否实际在程序中使用。

尽管MyFoo的所有成员函数都是内联的,但我相信编译器不会优化对CFoo_getLength()的调用,因为它无法知道此函数没有副作用。< / p>

问题:有没有办法实现这一点,只有在程序中实际使用了长度时才会调用CFoo_getLength()? (并且对于MyFoo对象,它永远不会被调用多次?)是否有办法允许编译器优化CFoo_getLength()调用(如果它足够聪明,可以推断它是不需要)?

一种方法是在类中有一个布尔标志,指示是否已经检索了长度:

class MyFoo2 {
    CFoo foo;

    bool lenKnown = false;
    int len;
public:
    MyFoo2(CFoo foo) : foo(foo) { }

    int length() {
        if (!lenKnown) {
            len = CFoo_getLength(foo);
            lenKnown = true;
        }
        return len;
    }
};

但这是一个运行时解决方案,它使MyFoo更大,并导致MyFoo::length()内的额外计算。我想知道是否有编译时解决方案。

1 个答案:

答案 0 :(得分:3)

您可以应用pure函数属性将CFoo_getLength标记为纯:

__attribute__ ((pure))
int CFoo_getLength(CFoo);

正如您所发现的,以及我的C ++ - 没有经验的惊喜,它允许gcc和clang优化您的原始代码。尼斯!