我们和朋友谈论功能和多线程。示例代码是:
void SomeClass::Foo()
{
std::lock_guard<std::mutex> lock(mMutexObj);
statement1;
statement2;
statement3;
}
因此,我们知道,有时编译器会在需要的地方内联函数。在这种情况下是否可能:编译器内联Foo
函数,所有3个语句都运行而lock_guard
不起作用,因为范围不会在这里结束而且没有析构函数调用:
// Inlined operations
std::lock_guard<std::mutex> lock(mMutexObj);
statement1;
statement2;
statement3;
// Global scope, where function was inlined continues here...
global statement1;
global statement2;
...;
有可能吗?编译器将内联这样的函数的百分之几,或者我不理解内联函数的范围?
答案 0 :(得分:9)
如果函数内联或不内联,或者内联或不内联声明,程序的可观察行为不会改变。在任何一种情况下,都会在适当的地方调用lock_guard的析构函数。同样,函数中的静态变量指的是同一个,即使它是内联的(d)也是如此。
答案 1 :(得分:3)
如果您使用#define
s /宏但未使用inline
,则会出现您所描述的效果。事实上,我认为引入内联的原因之一是避免因不当使用#define
而造成的大屠杀。
我认为范围是使用与使用{
和}
等效的方法保留的。
// Inlined operations
{ //curly braces create a scope
std::lock_guard<std::mutex> lock(mMutexObj);
statement1;
statement2;
statement3;
}
// Global scope
global statement1;
global statement2;
...;
注意上面使用花括号。这是完全有效的代码,当我必须在单个函数中的多个点锁定/解锁互斥锁时,我倾向于使用它。我猜编译器与内联函数类似。
答案 2 :(得分:2)
回答关于“编译器将内嵌这样的内容的百分比”的问题。给定一个“发布”版本(即具有高优化级别的构建),我希望所有现代的高质量编译器内联此代码,假设statement
不能解析为非常大的东西(例如,转换内联函数,内联另一个内联第三个函数的函数)。
我知道GCC会内联一个只调用一次的静态函数,即使它是巨大的,因为它基本上删除了一些指令,即使整个“基本”函数增加了几千字节。
当编译器认为它“有益”时,编译器会内联小函数,这当然是一个有弹性的术语。但是你几乎可以依赖于只做一些简单的事情,比如将几个整数加在一起,索引到一个向量或数组等,以便内联。如果函数有点复杂,例如有几个循环或几个调用其他函数,机会有点下降。
当然,虚拟函数不会被内联,除非它“显而易见”对象是什么。