<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                我們在編寫代碼的過程中經常會遇到一種叫做符號重復定義(Multiple Definition)的錯誤,這是因為在多個源文件中定義了名字相同的全局變量,并且都將它們初始化了。 例如,在 a.c 中定義了全局變量 global: ~~~ int global = 10; ~~~ 在 b.c 中又對 global 進行了定義: ~~~ int global = 20; ~~~ 那么在鏈接時就會出現下面的錯誤: ~~~ b.o: multiple definition of `global' a.o: first defined here ~~~ 這種符號的定義可以被稱為強符號。 在C語言中,編譯器默認函數和初始化了的全局變量為強符號(Strong Symbol),未初始化的全局變量為弱符號(Weak Symbol)。強符號之所以強,是因為它們擁有確切的數據,變量有值,函數有函數體;弱符號之所以弱,是因為它們還未被初始化,沒有確切的數據。 鏈接器會按照如下的規則處理被多次定義的強符號和弱符號: 1. 不允許強符號被多次定義,也即不同的目標文件中不能有同名的強符號;如果有多個強符號,那么鏈接器會報符號重復定義錯誤。 2. 如果一個符號在某個目標文件中是強符號,在其他文件中是弱符號,那么選擇強符號。 3. 如果一個符號在所有的目標文件中都是弱符號,那么選擇其中占用空間最大的一個。 比如目標文件 a.o 定義全局變量 global 為 int 類型,占用4個字節,目標文件 b.o 定義 global 為 double 類型,占用8個字節,那么被鏈接后,符號 global 占用8個字節。請盡量不要使用多個不同類型的弱符號,否則有時候很難發現程序錯誤。 在 GCC 中,可以通過`__attribute__((weak))`來強制定義任何一個符號為弱符號。假設現在有下面的一段代碼: ~~~ extern int ext; int weak1; int strong = 100; __attribute__((weak)) weak2 = 2; int main(){ return 0; } ~~~ weak1 和 weak2 是弱符號,strong 和 main 是強符號,而 ext 既非強符號也非弱符號,它是一個對外部變量的引用(使用)。 為了加深理解,我們不妨再來看一個多文件編程的例子。 main.c 源碼: ~~~ #include <stdio.h> //弱符號 __attribute__((weak)) int a = 20; __attribute__((weak)) void func(){ printf("C Language\n"); } int main(){ printf("a = %d\n", a); func(); return 0; } ~~~ module.c 源碼: ~~~ #include <stdio.h> //強符號 int a = 9999; void func(){ printf("c.biancheng.net\n"); } ~~~ 在 GCC 中,使用下面的命令來運行程序: ~~~ $gcc main.c module.c $./a.out a = 9999 c.biancheng.net ~~~ 在 main.c 中,a 和 func 都是弱符號,在 module.c 中,a 和 func 都是強符號,強符號會覆蓋弱符號,所以鏈接器最終會使用 module.c 中的符號,輸出結果也印證了這一點。 需要注意的是,`__attribute__((weak))`只對鏈接器有效,對編譯器不起作用,編譯器不區分強符號和弱符號,只要在一個源文件中定義兩個相同的符號,不管它們是強是弱,都會報“重復定義”錯誤。請看下面代碼: ~~~ #include <stdio.h> __attribute__((weak)) int a = 20; int a = 9999; int main(){ printf("a = %d\n", a); return 0; } ~~~ 這段代碼在編譯階段就會報錯,編譯器會認為變量 a 被定義了兩次,屬于重復定義。 弱符號對于庫來說十分有用,我們在開發庫時,可以將某些符號定義為弱符號,這樣就能夠被用戶定義的強符號覆蓋,從而使得程序可以使用自定義版本的函數,增加了很大的靈活性
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看