欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C?語言的弱符號與弱引用你了解嗎

 更新時間:2022年03月28日 10:23:46   作者:物聯(lián)網(wǎng)老王  
這篇文章主要為大家詳細(xì)介紹了C?語言弱符號與弱引用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

C語言中的__attribute__((weak)) 與 attribute ((weakref())

引言:最近在看 linux 中一些驅(qū)動代碼。驅(qū)動代碼中為了實現(xiàn)程序的擴展性和兼容性用了很多 C 語言中的高級特性。本節(jié)就來談一談 C 語言中的弱符號和弱引用的用法。

弱符號

弱符號是指在定義或者聲明一個對象(變量、結(jié)構(gòu)體成員、函數(shù))時,在對象的前面添加 __attribute__((weak)) 標(biāo)志所得到的對象符號。如下所示函數(shù)即為一個弱對象符號 void test_weak_attr(void),或者稱該函數(shù)是弱函數(shù)屬性的、虛函數(shù)。

__attribute__((weak)) void test_weak_attr(void)
// 或者使用如下樣式的定義,兩者等效
void __attribute__((weak)) test_weak_attr(void)
{
    printf("Weak Func!\r\n");
}

弱符號的作用與示例

弱符號是相對于強符號而言的,在定義或者聲明變量、函數(shù)時,未添加 __attribute__((weak)) 標(biāo)識的就默認(rèn)為強符號。如下,最普通的函數(shù)定義,就是定義了一個強符號 void test_strong_ref(void):

void test_weak_attr(void)
{
    printf("this is a strong func\r\n");
}

驅(qū)動程序往往需要考慮兼容性,因為要兼任很多廠商的不同型號的設(shè)備。若驅(qū)動程序中使用強符號定義一些與適配的設(shè)備的特性相關(guān)的功能,則下次適配其他設(shè)備時,該強符號函數(shù)可能需要被修改,以兼容新的設(shè)備。當(dāng)適配的設(shè)備很多時,頻繁地更改驅(qū)動代碼將破壞驅(qū)動的可維護性。

弱符號的出現(xiàn)可以很好地解決該問題。弱符號的對象具有可以被重定義的功能(即可以被重載)。下面通過測試說明弱符號這種可被重載的特性。

在 test_weak_attr.c 程序中定義如下弱函數(shù):

// test_weak_attr.c
#include <stdio.h>

__attribute__((weak)) void test_weak_attr(void)
{
    printf("this is a weak func\r\n");
}

在 main.c 中定義如下程序:

// main.c
void test_weak_attr(void)
{
    printf("this is a strong func\r\n");
}

void app_main(void)
{
    printf("init done\r\n");
    
    test_weak_attr();
}

編譯運行該 main.c 程序,得到的結(jié)果是什么樣子的呢?

this is a strong func

將 main.c 中的 void test_weak_attr(void) 函數(shù)注釋掉,再重新編譯運行程序得到的結(jié)果是:

this is a weak func

小結(jié):在使用弱符號函數(shù)時,我們可以重新定義一個同名的強符號函數(shù)來替代它;若沒有重新定義一個強函數(shù)來替換它,就使用弱函數(shù)的實現(xiàn)。弱函數(shù)就好像是一個可以被替換的“默認(rèn)函數(shù)”。

值得一提的是,舊版本的編譯器還可以使用如下方式的定義(僅聲明無效)將一個對象定義為一個弱對象:

__weak void f(void)
{
//code
}

在 linux 的一些代碼中,__weak 其實就是通過 __attribute__((weak))的重命名,兩者等效。

弱引用

弱引用是在聲明一個對象時,通過__attribute__ ((weakref()) 定義一個符號的引用關(guān)系。如下所示即定義 test_weakref() 函數(shù)弱引用 test_weak_ref() 函數(shù)。

static void test_weakref(void) __attribute__ ((weakref("test_weak_ref")));

弱引用是相對于強引用而言的。未通過 __attribute__ ((weakref()) 的符號和實現(xiàn)代碼之間的關(guān)系是強引用。如下即為一個強引用函數(shù)。它直接給出了 函數(shù) test_strong_ref(void) 的實現(xiàn)。

static void test_strong_ref(void)
{
    printf("this is a strong ref\r\n");
}

在編譯程序的時候,我們可以直接使用 test_strong_ref(void) 而不必?fù)?dān)心編譯不通過。如果,我沒有時間去實現(xiàn) test_strong_ref(void) ,還想在程序里先使用該函數(shù)那該如何呢?(是的,就是想白嫖,不想實現(xiàn),還想先在程序里使用這個函數(shù))。

這個時候弱引用就派上用場了。可以先將該函數(shù)定義為弱引用插入到代碼中,待后期有時間再慢慢優(yōu)化代碼實現(xiàn)這個函數(shù)完整的功能。下面結(jié)合測試進行說明。

測試代碼1:

static void test_weakref(void) __attribute__ ((weakref("test_weak_ref")));
void app_main(void)
{
    printf("init done\r\n");
    if (test_weakref) {
        test_weakref();
    } else {
        printf("There is no weakref\r\n");
    }
}

測試結(jié)果:

There is no weakref

測試代碼2:

void test_weak_ref(void)
{ 
    printf("this is a weak ref\n");
}
static void test_weakref(void) __attribute__ ((weakref("test_weak_ref")));
void app_main(void)
{
    printf("init done\r\n");
    if (test_weakref) {
        test_weakref();
    } else {
        printf("There is no weakref\r\n");
    }
}

測試結(jié)果:

this is a weak ref

小結(jié): 強引用,在未定義該強引用的實現(xiàn)時,編譯會報錯誤:未定義的引用。弱引用允許定義一個未實現(xiàn)(未實例化)的對象,這在編譯的時候會將該對象處理成 NULL,編譯器并不會報錯。通過使用弱引用可以實現(xiàn)后期優(yōu)化代碼的功能。而避免改動使用該函數(shù)的地方。使用弱函數(shù)可以實現(xiàn)類似“鉤子(hook)"函數(shù)的功能。

實際上,包括C、python、go 編程語言在內(nèi)的很多語言 都有類似用法,本篇文章敘述的方法同樣適用于這些語言的相關(guān)開發(fā)。

注意:弱引用僅在靜態(tài)編譯中有效,動態(tài)鏈接中可能無效。

總結(jié)

弱符號、弱引用都是增強程序的可維護性的方法。弱符號通過可以被重定義的特性,實現(xiàn)可以被替換實現(xiàn)。弱引用通過可以暫時使用一個未定義的函數(shù)的功能,實現(xiàn)允許后期再實現(xiàn)該函數(shù)具體功能,而不必?fù)?dān)心編譯不通過。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!    

相關(guān)文章

  • 基于C語言實現(xiàn)猜數(shù)字游戲

    基于C語言實現(xiàn)猜數(shù)字游戲

    這篇文章主要為大家詳細(xì)介紹了基于C語言實現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C語言內(nèi)存對齊實例詳解

    C語言內(nèi)存對齊實例詳解

    這篇文章主要介紹了C語言內(nèi)存對齊,包括內(nèi)存對其的基本概念及用法,以及注意事項,并以實例形式加以說明,需要的朋友可以參考下
    2014-09-09
  • C語言實現(xiàn)煙花表白程序代碼

    C語言實現(xiàn)煙花表白程序代碼

    大家好,本篇文章主要講的是C語言實現(xiàn)煙花表白程序代碼,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • C++使用VLD檢測內(nèi)存泄漏

    C++使用VLD檢測內(nèi)存泄漏

    本文主要介紹了C++使用VLD檢測內(nèi)存泄漏,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • OpenCV實現(xiàn)物體的凸包檢測的示例代碼

    OpenCV實現(xiàn)物體的凸包檢測的示例代碼

    給定二維平面上的點集,凸包就是將最外層的點連接起來構(gòu)成的凸邊形,它是包含點集中所有的點。本文將利用OpenCV實現(xiàn)物體的凸包檢測,感興趣的可以了解一下
    2022-08-08
  • C++實現(xiàn)在文本中找出某個單詞的位置信息

    C++實現(xiàn)在文本中找出某個單詞的位置信息

    本文給大家分享的是使用C++實現(xiàn)在文本中找出某個單詞的位置信息,就是給出此單詞所在的行和列,有需要的小伙伴可以參考下。
    2016-02-02
  • C++使用boost::lexical_cast進行數(shù)值轉(zhuǎn)換

    C++使用boost::lexical_cast進行數(shù)值轉(zhuǎn)換

    這篇文章介紹了C++使用boost::lexical_cast進行數(shù)值轉(zhuǎn)換的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 使用VS2022開發(fā)在線遠(yuǎn)程編譯部署的C++程序(圖文詳解)

    使用VS2022開發(fā)在線遠(yuǎn)程編譯部署的C++程序(圖文詳解)

    這篇文章主要介紹了使用VS2022開發(fā)可以在線遠(yuǎn)程編譯部署的C++程序,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • C++實現(xiàn)優(yōu)酷土豆去視頻廣告的方法

    C++實現(xiàn)優(yōu)酷土豆去視頻廣告的方法

    這篇文章主要介紹了C++實現(xiàn)優(yōu)酷土豆去視頻廣告的方法,實例分析了C++實現(xiàn)屏蔽功能的相關(guān)技巧,需要的朋友可以參考下
    2015-04-04
  • VC中BASE64編碼和解碼使用詳解

    VC中BASE64編碼和解碼使用詳解

    Base64是一種很常用的編碼方式,利用它可以將任何二進制的字符編碼到可打印的64個字符之中, 這樣,不管是圖片,中文文本等都可以編碼成只有ASCII的純文本。
    2015-11-11

最新評論