之前在除錯感測器模組的時候發現,在結構體宣告的時候irq成員使用gpio_to_irq會報錯,而動態使用的話就沒有問題。就對gpio_to_irq為什麼不能靜態使用產生了疑問。恰巧最近又有朋友遇到了同樣的問題,也就提醒了我,去找出原因。我寫了乙個簡單的linux執行程式進行測試,因為在核心原始碼中發現不同平台對gpio_to_irq的定義不同,有的是巨集定義,而更多的則直接是函式。所以在這個測試程式中我也以這一點作為切入點,進行測試。
編譯,果然出錯了:#include static int plus_one(int x)
struct test ;
struct test test1 = ;
int main(void)
可見,函式是不能作為結構體宣告靜態使用的。那麼改為動態試一試看:main.c:14:5: error: initializer element is not constant
.num = plus_one(5),
^main.c:14:5: error: (near initialization for 『test1.num』)
編譯,通過,能夠輸出想要的結果。struct test test1 = ;
int main(void)
結論:函式不能在結構體宣告等**中靜態使用,即使函式內容再簡單。只能以動態方式使用函式。在linux核心的omap2平台**中也印證了這一點,許多裝置資源都是在初始化函式中(即資源生效前)進行gpio_to_irq的動態賦值。
使用巨集定義代替上述**中的plus_one函式
編譯,通過,輸出我們希望的結果。這證明巨集定義可以靜態使用,那麼動態呢?#define plus_one(x) ((x) + 1)
... struct test test1 = ;
int main(void)
編譯,通過,輸出想要的結果。ok,這說明巨集定義同樣可以進行動態引用。struct test test1 = ;
int main(void)
結論:巨集定義在**中無論是靜態引用還是動態引用均可以。
通過測試**可以看出函式的使用有侷限性:只能動態引用,而不能靜態使用。巨集定義就顯得友好多了,靜態、動態使用均可。回到開始的問題gpio_to_irq為什麼不能靜態使用?就是因為很多平台**都將gpio_to_irq實現成為了函式,而非巨集定義,這樣就只能進行動態引用。但是,這在驅動編寫中也不是什麼問題,在上面已經說過,只要在裝置資源生效前(裝置註冊前)將其irq動態賦值好就可以了,現有的很多成熟平台也是這樣做的,並沒有問題。這裡我**這個問題只是因為自己的好奇心而已。
為何宣告語句不能放到if後面
如下 class test 以上 編譯不能通過。但是把宣告語句放到大括號中是可以的。具體的原因是if後面必須跟乙個語句,而單獨的賦值語句不是乙個語句。jsl中的定義如下 the ifthenstatement is defined like this ifthenstatement if expre...
靜態方法不能覆蓋
1.靜態方法只與定義時所在的類相關,在編譯期就已經繫結到某個類。可以繼承,但不能在子類中被同名方法覆蓋.網上有一句話 類的引用指向子類時,當用到方法時,呼叫的是子類的物件.當用到屬性時,用到的是父類物件.這個不適合靜態方法.測試如下 public class test1 static int myf...
靜態方法不能覆蓋
1.靜態方法只與定義時所在的類相關,在編譯期就已經繫結到某個類。可以繼承,但不能在子類中被同名方法覆蓋.網上有一句話 類的引用指向子類時,當用到方法時,呼叫的是子類的物件.當用到屬性時,用到的是父類物件.這個不適合靜態方法.測試如下 public class test1 static int myf...