inline Config& config()
{
static Config *c = new Config();
return *c;
}
上面的函数返回一个指向类Config的指针,在函数调用时创建一次。
C ++编译器是否能够正确内联此函数?
我的意思是c
是静态对象,第一次创建它会导致在代码中的某处内联new Config()
。但是当第二次调用该函数时,config()
的位置会是什么?内联c?还是函数调用?
答案 0 :(得分:3)
您似乎对此类静态变量的工作方式存在轻微的误解。看起来您认为编译器在第一次调用函数时会发出一组代码,而另一次会在另一次调用时发出另一组代码。事实并非如此。您可以考虑以下转换。
bool initialized = false;
Config* c;
inline Config& config() {
if(!initialized) {
c = new Config();
initialized = true;
}
return *c;
}
这是一个简化,但它得到了重点。该函数跟踪静态是否已初始化,如果没有,则执行此操作。每次调用该函数时都会进行检查。
考虑到这一点,静态变量的存在对特定函数的可嵌入性没有直接影响......编译器将简单地将检查与其他所有内容一起内联。问题很简单,这个新的扩展代码是否仍然满足编译器为内联函数提出的要求?它可能没有,但无论哪种方式,可见结果应该是相同的。
答案 1 :(得分:2)
这取决于编译器,但是从我在MSVC中看到的,它将内联两个全局变量来执行此操作(在汇编级别)。一个是bool,表示静态var是否被引入,另一个是实际静态var你的设置。
但是,应该注意inline
现在更像是一个暗示,所以函数可能永远不会被内联,只是因为编译器决定内联对象的构造函数而静态处理代码会导致太多臃肿等。
答案 2 :(得分:1)
如果内联器无法处理这样的微不足道的情况,那么根本就没有内联功能。
答案 3 :(得分:1)
如果我问的话,动态分配有什么意义?我会摆脱它:
inline Config& config()
{
static Config c = Config();
return c;
}
如果Config
不是POD,您甚至可以说static Config c;
并获得相同的语义。