程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++二進制兼容性

C++二進制兼容性

編輯:C++入門知識

學習、工作中總結的條款,不喜勿擾~

由於標准委員會一直沒有統一標准的C++ ABI,導致各個廠商都有自己的一套體系,為了不出意外,循規蹈矩也有一定的必要,但可以斟酌,三思而後行。


能:
1. 可以添加非virtual函數
2. 可以添加enum到class
3. 可以追加enum值到已存在enum中
4. 可以去掉private限制符沒有被inline函數調用或者被使用的且非virtual函數
5. 可以添加static數據成員
6. 添加新的class
7. 改變函數的默認參數
8. 改變class的friend修飾符


不能:
1. 對於已存在的class不能export or unexport
2. 改變class的繼承關系
3. 改變模板參數
4. 改變fucntion的unexport、remove、inline、重載
5. 改變函數簽名
6. 在不含有任何virtual成員的類添加virtual function
7. 改變virtual函數的順序
8. 重載已存在的virtual function
9. 對於non-private的static成員或者non-static、non-member的public數據不能unexport、改變類型、改變CV-qualifiers

 

為了將來class的擴展
1. Pimpl
2. 添加non-inline virtual destructor
3. 是所有的contructors non-inline


C++ABI
1. 對象的內存布局
2. 虛函數的調用方式,通常是vptr/vtbl然後用vtbl[offset]調用
3. name mangling(名字重整)
4. RTTI和exception
5. 調用約定(參數傳遞的方式)


源碼兼容但二進制不兼容
1. 給函數增加默認參數
2. 增加虛函數,會造紙vtbl的排列變化(只在末尾增加有問題,該class可能已被繼承)
3. 增加默認模板參數類型,改變了name mangling
4. 改變已有enum的值
5. 增大class數據成員,造成sizeof變大


安全的做法
1. 增加class
2. 增加non-virtual成員函數
3. 修改數據成員名稱,二進制代碼是按偏移量訪問
4. ...


解決方案
1. 靜態鏈接
2. 動態庫的版本管理來控制兼容性
3. PIMPL,頭文件之暴露non-virtua;接口,並且class的大小固定

補充一點,COM的思想和做法有他的歷史局限性,不過也相當完備,但是,我不推崇。


摘自 chenyu2202863

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved