2013-08-06 66 views
0

我们正在和我的朋友讨论函数和多线程。示例代码为:互斥和内联函数

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

允许内部更改范围吗?我总是想象它会在任何被复制的周围添加'{'和'} ... – 2013-08-06 21:34:29

+0

@ebyrob我认为改变范围会造成严重破坏。使用#defines会做到这一点。我认为内联函数的一个原因是为了避免#defines引起的问题 – maditya

回答

9

如果一个函数是内联的,或者内联或不内联,程序的可观察行为都不会改变。在这两种情况下,lock_guard的析构函数都会在适当的位置被调用。同样,函数中的静态变量也是指同一个,即使它是内联的(d)。

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

只是为了回答关于“百分比编译器将内联这样的内容”的问题。给定一个“发布”版本(即具有较高优化级别的版本),我期望所有现代高质量的编译器内嵌此代码,假设statement不会解析为某些非常大的内容(例如依次内联函数这是内联第三个函数的另一个函数)。

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

编译器只要编译器认为它是“有益的”就内联小函数,这当然是一个有弹性的术语。但是你几乎可以依赖一些只能做一些简单事情的东西,比如像添加一些整数,索引到一个向量或数组等等,以便内联。如果功能有点复杂,例如有几个循环或几个呼叫到其他功能,机会有所下降。

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