2014-10-17 37 views
0

在處理Arduino庫時,我遇到了一個有趣的編譯問題。所有類中的所有虛擬方法都會被編譯...始終。即使課程從未構建或甚至提及。如何防止始終編譯虛擬方法?

例Arduino的代碼再現此問題:

class BaseClass { 
    virtual void method(); 
}; 

void BaseClass::method() { 
    Serial.println("This should not be compiled at all..."); 
} 

void setup() { 
} 

void loop() { 
} 

離開出的670個字節的最終二進制的BaseClass的結果。包括它,而從來沒有使用類,導致代碼大小爲3.354字節。

對於包含大量永遠不會被使用的類的庫,所有類都包含虛擬update()例程,這種行爲是不可接受的。到目前爲止我發現的唯一解決方案是強制用戶爲他希望使用的組件包含頭文件。不過,我最好保持圖書館簡單,不要求用戶這樣做。

是否有一個AVR方法屬性,可以告訴編譯器只編譯一個虛擬方法,如果該類正在構建某處?另外,是否有編譯器選項可以使我優化這些未使用的虛擬方法?

使用ATMEGA2560 AVR和G ++編譯器。通過Arduino的通過當前的編譯器選項:

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega2560 -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106 -IC:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\variants\mega 
+2

也許'-fvtable-gc'是你想要的嗎? ([Source](https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/C---Dialect-Options.html))你可能需要額外的選項來實際拋出方法實現。查看鏈接。 – cdhowie 2014-10-17 23:02:43

+0

看起來像這是解決方案,一旦我找到一種方法來改變Arduino軟件中的編譯器選項,我可以確定它是否有效。 – bergerkiller 2014-10-18 11:19:17

回答

0

使用-fno-implicit-templates你可能會解決你眼前的問題,你就必須實例化這些模板明確你使用。

您的用戶將不得不包含一個標題,其中包含所有未實例化的模板的完整實現,併爲他們所使用的模板使用正確的標記/顯式實例化。

+0

將此標記標記爲已接受的回答,以將線程標記爲已回答。這可能是一個同樣可以接受的解決方案,儘管我還沒有設法試用它。 – bergerkiller 2014-10-30 17:23:03