1. 程式人生 > >GCC/LD編譯連結潛規則(前方大坑,注意避讓)

GCC/LD編譯連結潛規則(前方大坑,注意避讓)

當一個符號在多個目標檔案(.o)裡同時出現時, LD報錯. 提示符號多重定義.

當一個符號在多個靜態庫(.a)裡同時出現時,或多個靜態庫和一個目標檔案同時出現時, LD不報錯, 以第一個遇到的為準. 並且不會有任何warning提示 !!! 這個規則可能導致很多意想不到的問題!!!

補充一些:

GCC/LD在

1.做符號解析時,會把找到的第一個定義的程式碼連結進來(已經找到了就不再考慮後續的)

2.做Object連結時(*.o檔案),每一個目標檔案要做reloc操作,找到的第一個定義優先處理,再遇到一個相同的定義,就報"multip-definition 錯誤",這個可以通過-Wl,'-z muldefs'來解決,

-z muldefs會讓ld在遇到重複定義時候,只處理第一個定義。

在執行時刻,如果:

1.存在多個相同的動態庫名,則根據ldconfig中配置的庫查詢路徑,先找到哪個就用哪個。如果機器中存在不同版本的動態庫,則可能會用上錯誤的庫,而從我們的程式碼中是檢查不出錯誤的,

只能優先做"ldconfig -p | grep 庫名"的檢查,幹掉一個不用的庫就可以。

2.如果多個不同的動態庫,擁有相同的全域性變數名,則最後載入的動態庫中的全域性變數會沖掉之前載入的全域性變數,導致結果異常(程式正常工作)

下面這篇文章對連結處理的說明的比喻挺貼切的:

另外,對比VC++的行為,是不一樣的,VC++在發現安多個依賴庫中有同名符號時,會符號重定義,而不是預設的選擇一個,同時,VC++還提供了當符號重定義時忽略制定的庫的能力

相關推薦

GCC/LD編譯連結規則前方大坑注意避讓

當一個符號在多個目標檔案(.o)裡同時出現時, LD報錯. 提示符號多重定義. 當一個符號在多個靜態庫(.a)裡同時出現時,或多個靜態庫和一個目標檔案同時出現時, LD不報錯, 以第一個遇到的為準. 並且不會有任何warning提示 !!! 這個規則可能導致很多意想不到

jadx反編譯—下載和使用傻瓜教程非常詳細

一、在GitHub上直接下載 https://github.com/skylot/jadx 可以下這個版本: 二、執行圖形化介面 1、將zip檔案解壓後定位到在lib資料夾中,在此處開啟命令列 2、執行jadx-gui-0.7.1.jar(前提是已經裝好了JDK1

打碼C語言常見粗心小錯誤 前方高能一定要點

打碼(C語言)常見粗心小錯誤 標籤(空格分隔): 部落格 目錄 1.前言 小萌新們是不是經常打完碼之發現程式執行達不到自己的效果,然後自己用大腦執行的時候發現完全沒有問題,然後發截圖給TA,最後發現原來是自己一些粗心的小問題導致程式

760B 】Frodo and pillows 二分題意注意細節

題幹: n hobbits are planning to spend the night at Frodo's house. Frodo has n beds standing in a row and m pillows (n ≤ m). Each hobbit nee

Linux系統使用入門進階總結6——Ubuntu下gcc/g++編譯連結過程

文章轉自: https://blog.csdn.net/VennyJin/article/details/82794331 這裡講的是最簡單的c/c++檔案在linux下編譯連結的過程,後期還可以使用cmake來完成更復雜的工程構建過程。請關注博主的後續文章哈~~~ Ubuntu下gcc

【C程式編譯連結gcc使用命令介紹 GCC編譯器編譯連結  

1.gcc安裝 rpm -qa|grep gcc ==>檢查gcc是否安裝 gcc -v ==>檢查gcc版本 yum -y install gcc ==>安裝gcc  2.基本語法 gcc最基本的用法是:gcc [options]

http協議--Apache-Httpd服務基本配置-rpm安裝-編譯安裝HTTP2.2HTTP2.4

超文本標記語言 cookie信息 multiview 異步 表達 tp服務器 The 計算 改變 socket: OSI七層: 上三層:用戶空間 下四層:通信子網,內核空間 ip:主機到主機通信 M

MyBatis之自定義對映規則連線查詢需要修改對應對映時使用

自定義對映規則:即自己定義資料庫與Bean物件的對映規則,不再使用預設Bean物件與記錄同名規則,即每個資料庫                             的屬性都可以決定它對映到哪個類的哪個屬性, 所以操作標籤(如<select>)的resultT

LeetCode 92. 反轉連結串列 IIC、C++、python

反轉從位置 m 到 n 的連結串列。請使用一趟掃描完成反轉。 說明: 1 ≤ m ≤ n ≤ 連結串列長度。 示例: 輸入: 1->2->3->4->5->NULL, m = 2

資料結構篇:單迴圈連結串列倒置帶頭結點/不帶頭結點

帶頭結點 先去看一下單鏈表的倒置:https://blog.csdn.net/qq_15020543/article/details/84590642 對於單迴圈連結串列,它與單鏈表區別是,它的最後一個結點將指向頭結點(無頭結點將指向第一個結點),構成一個迴圈. 遍歷迴圈連結串列的時

線性表之連結串列複習僅王道單鏈表題目

考研408複習,如發現任何錯誤,請私聊,不勝感謝 單鏈表程式碼已更新完畢。 如下: #include <iostream> #include <algorithm> #include <string> #include <cma

驗證身份證號規則驗證身份證號是否正確

案例: 某公民的身份證號: 34052419800101001X  (18位) 加權因子表: 位置序號 1 2 3 4 5 6 7 8 9 10 11 12 13

VS開啟工程編譯後報錯VS編譯器各版本代號

VS編譯器各版本代號 ------------------------------------------------------ MSVC++ 14.1 _MSC_VER == 1910 (Visual Studio 2017) MS VC++ 14.0 _MSC_VER = 1900

libiconv 交叉編譯和呼叫方法UTF-8和GB2312轉換

1、解壓 libiconv-1.14.tar.gz;進入libiconv-1.14目錄 2、./configure --host=arm-none-linux-gnueabi --enable-shared --enable-static --prefix=/opt/lib

交叉編譯環境的搭建Linux-2.6.32核心

1、建立安裝目錄 #mkdir /usr/local/arm 如果您的PC 端linux 系統已經有這個資料夾,這步就跳過 2、將交叉編譯工具解壓到安裝目錄(注意C是大寫) #tar -xjvf arm-linux-gcc-4.3.2.tar.

關於修改springboot中redis配置中的修改RedisTemplate 預設的序列化規則修改成JSON資料型別

原理:覆蓋預設配置類; 在建立的springboot專案中的啟動類中: public static void main(String[] args) { SpringApplication.run(TestspringBoot0

Win64下編譯OSG詳細過程Win10+VS2015+OSG3.6.3

新建 art osg 類庫 動態庫 查找 測試環境 lease ring 目錄 1. 數據資源準備 2. 編譯第三方庫 3. 編譯GDAL 4. 編譯OSG

程式的連結與裝入動、靜態重定位

 原由:   多道程式環境下,程式是併發執行的,所以要使程式執行,必須先為之建立程序,而建立程序的第一件事就是將程式和資料裝入記憶體     目的:     使用者程式到記憶體可執行程式的步驟:   

win手動編譯JAVA 未完成系統path未加入文章

pretty ces rec 新建 top sources neon txt print java 下面存。BAT dir /s /B *.java > sources.txtjavac @sources.txt -bootclasspath "C:\Users\

初遇C#:一個簡單的小程序圓形周長面積計算器

編碼 雙精度 崩潰 輸入 面向對象 窗口 語句 readline 面向對象的語言 作為一個面向對象的語言,與用戶的交互很關鍵! 在此,我們可以先分析一下我們這個小程序要與用戶交互的內容:1.命名很重要,讓用戶看見這個程序就知道這個程序的作用。 2.當用戶打開這個程序時,提示