編譯器的詞法分析和語法分析是如何處理C++的模板?
不考慮可變模板參數,不考慮模板的模板參數,不考慮偏特化,僅考慮模板的類型參數和非類型參數.是不是用LL解析器或者LR解析器就可以成功解析出包含這種模板子集的AST?
你的這個問題實在太大了,建議再縮小一下,編譯器解析模板我覺得我在我的博客完全可以寫個十幾篇的連載。
我這裡就說一個小方面吧,就是模板的實例化的選取,即編譯器與鏈接器如何確保在執行的時候只有一份模板實例,因為我們知道編譯器遇到模板實例化的時候就會實例化一份(而還有模板的特化順序處理,Candidate選取等這裡都不講,所以我說你這個問題實在太大太大了),而講這個問題是可以引導出C++11用於提高Compiler Performance的extern template新特性(注意不是export)。那麼我這裡簡單提一下IBM的XL C++編譯器如何處理模板的(我想其它編譯器應該也有類似的思路),模板和普通的程序在IBM XL C++編譯器中走的是兩條道路,即他們不是在一條道路上的。遇到模板的時候,編譯器都會「壓制」到後面來處理。而IBM XL C++ Compiler為了完成模板實例化選取,然後保證鏈接器只會拿一份實例,對模板採取了一個特殊的處理,就是使用了weak symbols. 舉一個簡單的例子吧
// a.h
template &
// 1.cpp
#include "a.h"
int fun1()
{
f(1);
}
// 2.cpp
#include "a.h"
int fun2()
{
f(2);
}
我們這裡在1.cpp會生成一份f&
// a.h
template &
extern template int f&
// 1.cpp
#include "a.h"
template int f&
int fun1(){
f(1);
}
// 2.cpp
#include "a.h"
int fun2(){
f(2);
}
現在的情況就是在a.h聲明了模板,而在1.cpp顯示實例化了f&
其實我們回過頭看這個特性,其實思想和以前的extern是類似的,只是這次遷移到了模板而已。那麼這個特性有沒有一些注意項呢?我認為有如下幾點。
1. 該特性適用於函數模板和類模板2. 如果你先聲明了extern template,卻沒有顯示實例化,那麼會報鏈接錯誤3. 不能用於靜態函數模板(這個是比較顯而易見的)4. C++11沒有聲明是否可以用於inline,這是未定義的行為5,.不應過度依賴此特性,應該將這個特性用在實例化頻繁的地方。
我好像針對你的提問,只講了一個非常非常小的地方,但是說了這麼多,好像又什麼沒有講一般,還是因為C++模板太複雜了。推薦閱讀:
※你對基於機器學習的編譯技術有什麼看法?
※為什麼C++預處理期編譯期的支持比較薄弱?
※想用用flex和bison寫個C的編譯器,應該如何處理C的宏?
※peg, ometa 解決什麼問題,ometa-js怎麼入門/正確理解和認知?
※(發散性問題,請隨意加上假設)一門編程語言同時擁有解釋器和編譯器的必要性有多大?