整容说文库 > 程序代码 > 教育资讯

请高手帮忙,内联函数问题!

来源:学生作业帮助网 编辑:整容说文库 时间:2021/01/28 07:14:10 程序代码
请高手帮忙,内联函数问题!程序代码
最近要写一个大一点的程序,效率上是个问题,有几百个函数,而且部分函数调用频繁,(如果可能的话,要求12M次/秒)因此考虑到效率问题想使用内联函数,但我从来没用过内联函数,不知道会不会有问题

VC提供__forceinline  __inline,但似乎要求和限制很多,而且不一定成功,请高手给点内联函数的使用经验,谢谢!

比如在一个对象中调用另一个类中的内联函数能否成功(这个内联函数需要操作本实例中的一些变量)

另外感觉内联和宏调用好像差不多,到底有什么区别?请多指教
up
关注!
gz
内联函数是在调用处直接嵌入函数体源的函数,实现机制和函数完全不同,确实和宏几乎一样,但它的参数类型检查却和函数一样,对于类型不一致还进行类型转换,对比之下,宏就不会进行这样的检查和转换。还有一个很大的区别,内联函数参数传递时值只取一次,而宏由于是直接替换,所以可以计算多遍。比如:
int x=5,y=2;
int k=max(x++,y++);
如果max是内联函数,则k=6;如果是宏,则k=7;
(凡有循环语句或switch语句等的函数不能成为内联函数)
内联函数的作用几乎和宏的作用一样,它也是将内联函数代码直接扩展替代调用语句。同时,它既然也称“函数”它就具有一般函数的参数类型检测和转换功能。使用中效率要比宏的效率高。
   在一个对象中可以调用另一个类中的内联函数,但是这个内联函数要有被外部访问权限。
内联函数比宏安全!
inline已经很明确了,给你宏的便利`却又提供函数般的安全~
不过...谁说宏过时了我跟谁急(笑),去看看MFC里面几个宏,写的实在是经典~
宏在定义常量时候的却显的过时了,但是...有些方面你必须得用它~
d
Macro 如果写得好,还是不错的^_^

我写内联函数一般用 inline 修饰,不知道 VC 的 __inline 那些。
内联函数只是对编译器的一个“建议”。如果函数体不够要求(太长、包含循环、静态变量?。。。等等吧,就是说不够简洁)的话还是作为普通函数被调用的。

可以调用其它类的具有访问权限的内联函数。是否展开我不知道(不懂汇编,没办法。。。)
关键是 inline 如果编译器认为对这个函数不适合 它会自动忽略
比如递归之类

要看看原代码才能确定能不能inline了。
// a.h: interface for the a class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_A_H__D9DFC955_7C20_4569_A2FD_8BD0CADD1130__INCLUDED_)
#define AFX_A_H__D9DFC955_7C20_4569_A2FD_8BD0CADD1130__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class a  
{
public:
UINT PCS;

__forceinline void funa(int x,int y);
a();
virtual ~a();


};


#endif // !defined(AFX_A_H__D9DFC955_7C20_4569_A2FD_8BD0CADD1130__INCLUDED_)



// a.cpp: implementation of the a class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "test.h"
#include "a.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

a::a()
{
PCS=0;
}

a::~a()
{

}

__forceinline void a::funa(int x, int y)
{
PCS=PCS+x+y;
}



// b.cpp: implementation of the b class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "test.h"
#include "b.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

b::b()
{

}

b::~b()
{

}

void b::funb()
{
obja.funa(10,20);
}



// b.h: interface for the b class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_B_H__C343AC3E_666E_4E85_B559_2FAD973F4230__INCLUDED_)
#define AFX_B_H__C343AC3E_666E_4E85_B559_2FAD973F4230__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class b  
{
public:
void funb();
b();
virtual ~b();

};

#endif // !defined(AFX_B_H__C343AC3E_666E_4E85_B559_2FAD973F4230__INCLUDED_)




// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__461FD2B7_BDB9_410D_84AF_A74866A398E6__INCLUDED_)
#define AFX_STDAFX_H__461FD2B7_BDB9_410D_84AF_A74866A398E6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

#include <afx.h>
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

#include <iostream>
#include "a.h"
#include "b.h"
extern a obja;
// TODO: reference additional headers your program requires here

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__461FD2B7_BDB9_410D_84AF_A74866A398E6__INCLUDED_)



// stdafx.cpp : source file that includes just the standard includes
// test.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"
a obja;
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
  



// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "test.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

#include <iostream>
using namespace std;


int main()
{
b objb;
objb.funb();
return 0;
}
可以考虑用宏替换
谢谢大家帮忙,我上面的的代码中类a中Funa能不能使用内联汇编?
使用__forceinline 后,VC连接时出现错误,提示如下
b.obj : error LNK2001: unresolved external symbol "public: void __thiscall a::funa(int,int)" (?funa@a@@QAEXHH@Z)
Debug/test.exe : fatal error LNK1120: 1 unresolved externals
MSDN says:
The __inline keyword is equivalent to inline.

Even with __forceinline, the compiler cannot inline code in all circumstances. The compiler cannot inline a function if: 

The function or its caller is compiled with /Ob0 (the default option for debug builds). 
The function and the caller use different types of exception handling (C++ exception handling in one, structured exception handling in the other). 
The function has a variable argument list. 
The function uses inline assembly, unless compiled with /Og, /Ox, /O1, or /O2. 
The function returns an unwindable object by value, when compiled with /GX, /EHs, or /EHa. 
The function receives an unwindable copy-constructed object passed by value, when compiled with /GX, /EHs,, or /EHa. 
The function is recursive and not accompanied by #pragma inline_recursion(on). With the pragma, recursive functions can be inlined to a default depth of eight calls. To change the inlining depth, use inline_depth pragma. 
The function is virtual and is called virtually. Direct calls to virtual functions can be inlined. 
The program takes the address of the function and the call is made via the pointer to the function. Direct calls to functions that have had their address taken can be inlined. 
The function is also marked with the naked __declspec modifier. 
If the compiler cannot inline a function declared with __forceinline, it generates a level 1 warning (4714).

Recursive functions can be substituted inline to a depth specified by the inline_depth pragma. After that depth, recursive function calls are treated as calls to an instance of the function. The inline_recursion pragma controls the inline expansion of a function currently under expansion. See the Inline-Function Expansion (/Ob) compiler option for related information. 

楼上的: error?不晓得了^_^
我觉 得这里的a.funa是能内联的,直接用inline估计就可以了。又不是复杂的不西
通过内联来提高效率?
一些频繁使用的且与对象无关的函数用内联或宏,当然会快一点;至于提高系统的效率嘛,呵呵,我认为主要是算法的问题,试想在汇编一级,函数调用仅仅是进行了一些地址跳转。我们应该先看看这些在这个内联函数所占的比重多大,然后再来考虑内联的问题似乎会好一点。
我觉得主要用在:
诸如:图像处理中对每个像素的RGB进行一定的算法处理,这时候内联就很有必要了。
还有一些数学计算上面
关注中。。。
程序代码