C++編譯重複代碼消除

在編譯c++文件的時候會產生很多重複代碼,如擴展模板的時候,在不同的源文件裏使用了相同的模板,那在編譯各個源文件的時候都會針對該模板分別生成一樣的目標代碼,這部分代碼就是重複代碼。如果鏈接的時候直接把他們都鏈接進來,無疑是很浪費的事。爲了解決這個問題,編譯器會把同樣的代碼編譯到相同的段,鏈接時就容易進行消除了。那如果編譯到同樣段的代碼實際上是不同的,鏈接是否會出錯?通常這種情況下連接器會隨機選擇一個副本作爲輸入,並給出警告信息。
我們來試一下:
mian.cpp:

	#include <iostream>


	extern int int_add(int a, int b);
	extern int int_sub(int a, int b);




	int main(int argc, char **argv)
	{
		int a = 10;
		int b = 7;
		int result = int_add(a,b);
		std::cout<<"int_add result:"<<result<<std::endl;
		result = int_sub(a,b);
		std::cout<<"int_sub result:"<<result<<std::endl;
		return 0;
	}






t1.cpp:

	template <typename T> T add(T a, T b)
	{
		return a + b;
	}


	int int_add(int a, int b)
	{
		return add(a,b);
	}




t2.cpp:

	template <typename T> T add(T a, T b)
	{
		return a - b;
	}


	int int_sub(int a, int b)
	{
		return add(a,b);
	}




編譯運行的結果如下:
int_add result:17
int_sub result:17


可見int_sub沒有鏈接自己的模板。我們再看看如果不把t1.cpp鏈接進來會怎樣。
把main.cpp改爲:

#include <iostream>


//extern int int_add(int a, int b);
extern int int_sub(int a, int b);




int main(int argc, char **argv)
{
	int a = 10;
	int b = 7;
	//int result = int_add(a,b);
	//std::cout<<"int_add result:"<<result<<std::endl;
	int result = int_sub(a,b);
	std::cout<<"int_sub result:"<<result<<std::endl;
	return 0;
}




編譯運行結果:
int_sub result:3


這次就鏈接了t2.cpp裏的模板了。


不過我的問題是,我是在Mac下編的,竟然連個警告都沒有。在實踐中怎樣規避這樣的風險呢?是否尅通過命名空間來規避呢?我們看看增加命名空間後會怎樣。
main.cpp:

#include <iostream>
namespace t1{
extern int int_add(int a, int b);
}
namespace t2{
extern int int_sub(int a, int b);
}




int main(int argc, char **argv)
{
	int a = 10;
	int b = 7;
	
	int result = t1::int_add(a,b);
	std::cout<<"int_add result:"<<result<<std::endl;


	result = t2::int_sub(a,b);
	std::cout<<"int_sub result:"<<result<<std::endl;


	return 0;
}




t1.cpp:
namespace t1{
	template <typename T> T add(T a, T b)
	{
		return a + b;
	}


	int int_add(int a, int b)
	{
		return add(a,b);
	}
}




t2.cpp:
namespace t2{
	template <typename T> T add(T a, T b)
	{
		return a - b;
	}


	int int_sub(int a, int b)
	{
		return add(a,b);
	}
}



編譯運行:
int_add result:17
int_sub result:3


這次正常了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章