0

we were talking about function and multithreading with my friend. The sample code was:

void SomeClass::Foo()
{
   std::lock_guard<std::mutex> lock(mMutexObj);

   statement1;
   statement2;
   statement3;
}

So, we know, that sometimes compiler inlines the functions where it's needed. Is it possible in such case: compiler inlines the Foo function, all the 3 statements run and lock_guard doesn't work because scope doesn't end here and no destructor called:

// Inlined operations
std::lock_guard<std::mutex> lock(mMutexObj);

statement1;
statement2;
statement3;

// Global scope, where function was inlined continues here...
global statement1;
global statement2;
...;

Is it possible? What percent that compiler will inline such function or maybe I don't understand right the scope of inlined function?

4

3 回答 3

9

无论函数是否内联,或声明内联与否,程序的可观察行为都不会改变。在任何一种情况下,lock_guard 的析构函数都会在适当的位置被调用。同样,函数中的静态变量指的是同一个变量,即使它是否是 inline(d) 也是如此。

于 2013-08-06T21:34:37.760 回答
4

如果您使用#defines/macros 但不使用inline. 事实上,我认为引入内联的原因之一是为了避免因使用不当造成的大屠杀#define

我相信使用等同于使用{and的方法保留了范围}

// Inlined operations
{  //curly braces create a scope
  std::lock_guard<std::mutex> lock(mMutexObj);

  statement1;
  statement2;
  statement3;
}

// Global scope
global statement1;
global statement2;
...;

注意上面花括号的使用。这是完全有效的代码,当我必须在单个函数中的多个点锁定/解锁互斥锁时,我倾向于使用它。我猜编译器对内联函数做了类似的事情。

于 2013-08-06T21:45:21.220 回答
2

只是为了回答有关“编译器将内联这样的内容的百分比”的问题。给定一个“发布”构建(即具有高优化级别的构建),我希望所有现代的高质量编译器都内联此代码,假设它statement不会解析为非常大的东西(例如,反过来内联一个函数内联另一个内联第三个函数的函数)。

我知道 GCC 将内联一个只调用一次的静态函数,即使它是巨大的,因为它本质上删除了一些指令,即使整个“基本”函数变大了几千字节。

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

当然,虚函数不会被内联,除非它是“明显的”对象是什么。

于 2013-08-06T22:20:04.103 回答