互斥和内联函数

时间:2013-08-06 21:30:31

标签: c++ multithreading scope

我们和朋友谈论功能和多线程。示例代码是:

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;
...;

有可能吗?编译器将内联这样的函数的百分之几,或者我不理解内联函数的范围?

3 个答案:

答案 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会内联一个只调用一次的静态函数,即使它是巨大的,因为它基本上删除了一些指令,即使整个“基本”函数增加了几千字节。

当编译器认为它“有益”时,编译器会内联小函数,这当然是一个有弹性的术语。但是你几乎可以依赖于只做一些简单的事情,比如将几个整数加在一起,索引到一个向量或数组等,以便内联。如果函数有点复杂,例如有几个循环或几个调用其他函数,机会有点下降。

当然,虚拟函数不会被内联,除非它“显而易见”对象是什么。