C++ 有没有一种方法允许编译器优化对外部函数的多次调用?
我正在构造一个类似于C库的C++接口:C++ 有没有一种方法允许编译器优化对外部函数的多次调用?,c++,optimization,compile-time,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()
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\u getLength()
<> P> C++接口意味着使用更简单,让用户只使用<代码>长度()/<代码>,而不需要考虑性能。上述实现的缺点是,它总是在创建每个MyFoo
对象的过程中调用CFoo\u getLength()
,而不管它是否将实际用于程序中
即使MyFoo
的所有成员函数都是内联函数,我相信编译器不会优化对CFoo_getLength()
的调用,因为它无法知道此函数没有副作用
问题:是否有办法实现此功能,以便只有在程序中实际使用长度时才会调用CFoo\u 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()
中的额外计算。我想知道是否有编译时解决方案。您可以应用pure
函数属性将CFoo\u getLength
标记为pure:
__attribute__ ((pure))
int CFoo_getLength(CFoo);
正如您所发现的,令我C++缺乏经验的惊讶的是,它允许gcc和clang优化您的原始代码。很好 如果
CFoo
的长度从直觉上来说确实是一个长度,那么您就可以去掉大小惩罚。@StoryTeller:哦,好的。那么,允许从其他地方链接实现的正确方法是什么?(这是否意味着当我编译单个.cpp
文件时,其中包含.o
s的标题,这很危险?@Ryan-我不能说是在线编译器。我目前实际上没有访问GCC的权限来进行验证。“我不是想在游行上泼冷水,我只是想指出OP需要做一些更严肃的测试,而不仅仅是对godbold的测试。”Ryan-关于你的简化问题。这并不危险。ODR方面涉及整个程序,而不是单个翻译单元。所以,只要你在最后把所有的东西都链接起来,你就可以去了。@Szabolcs-在联机编译器中不是这样的。我的全部观点是,它在godbolt(存在ODR违规的地方)中工作的事实并不表明它一般是否应该工作。但是如果是这样的话,在你自己的项目中,对你来说很好:)我正在阅读,似乎合适的属性实际上是pure
(而不是const
)。文档中说,“请注意,具有指针参数并检查指向的数据的函数不能声明为常量。”对pure
@Szabolcs:Yikes没有这样的限制,我记错了。谢谢