gcc下inline的一個問題


今天發現一個問題,與inline有關,也與編譯時候是不是優化有關。
大概問題可以用下面的代碼來描述:

先寫一個libtest1,代碼如下
libtest1.h

#ifndef LIBTEST_H
#define LIBTEST_H

class Test{
	public:
		inline void fun1()const;
		void fun2()const;
};
#endif //!LIBTEST_H

libtest1.cpp

#include <stdio.h>
#include "libtest.h"

void Test::fun1()const
{
	puts("fun1");
}

void Test::fun2()const
{
	fun1();
	puts("fun2 call fun1");
}

編譯為動態庫,使用命令為:gcc -shared -fpic libtest.cpp -o libtest1.so

然后第二個動態庫libtest2,代碼如下

#include "libtest.h"

extern "C" void fun3()
{
	Test t;
	t.fun1();
	t.fun2();
}

編譯命令為:gcc -shared -fpic libtest2.cpp -o libtest2.so -Wl,-rpath=. -L. -ltest1

然后寫測試代碼,運行時加載libtest2.so,然后調用fun3函數。代碼如下

#include <stdio.h>
#include <dlfcn.h>

typedef void (FuncType)();

int main()
{
	//void* p = dlopen("./libtest2.so",RTLD_NOW);
	void* p = dlopen("./libtest2.so",RTLD_LAZY);
	if(p == NULL){
		printf("dlopen libtest2.so failed:%s\n",dlerror());
		return 0;
	}
	FuncType* f1 = (FuncType*)dlsym(p,"fun3");
	if(f1 == NULL){
		printf("dlsym fun3 failed:%s\n",dlerror());
		return 0;
	}
	f1();
	dlclose(p);
	return 0;
}

編譯執行結果如下:

/home/o/sopath [o@o-pc] [13:40]
> gcc test.cpp -o test -ldl                                            

/home/o/sopath [o@o-pc] [13:41]
> ./test 
fun1
fun1
fun2 call fun1

看起來好像沒有問題,但是這里編譯的時候都沒有進行優化,使用的默認選項,如果我們編譯命令修改一下,則就變了

/home/o/sopath [o@o-pc] [13:34]
> gcc -shared -fpic libtest.cpp -o libtest.so -O3
/home/o/sopath [o@o-pc] [13:41]
> ./test 
./test: symbol lookup error: ./libtest2.so: undefined symbol: _ZNK4Test4fun1Ev

這時候就找不到fun1這個函數了,使用strings libtest1.so也確實找不到。但是如果把fun1前面的inline去掉,就沒有問題了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM