程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 跨C++文件和庫對靜態對象進行初始化

跨C++文件和庫對靜態對象進行初始化

編輯:關於C++

假期通常是個回顧過去的好時候。這裡就是我正在思考的上個月使我產生"ah-hah"瞬間的一個 問題。

問題:

當你編譯下面的C++程序的時候,你可能認為模塊(module)中的對象會先編譯並先初始 化。

這種假設可能得不到預期的結果。

X.h :

#include <string>

using namespace std;    // 譯者注: 加上這行

class CObjet {

 public:

    static const string STRINGX;

};

X.cpp:

#include <X.h>

using namespace std;    // 譯者注: 這行可以不要

const string CObjet::STRINGX = "001";

Y.cpp:

#include <iostream>

#include <X.h>

const string STRINGY= CObjet::STRINGX;

int main () {

cout << "CObjet::STRINGX [" <<CObjet::STRINGX << "]" << endl;

cout << "STRINGY [" <<  STRINGY << "]" << endl;

return 0;

}

如果用下面的命令來編譯:

xlC -c -I./ X.cpp -o X.o

xlC -c -I./ Y.cpp -o Y.o

xlC -o binary X.o Y.o

然後得到的結果如下:

./binary

CObjet::STRINGX [001]

STRINGY []    // 譯者注: 該結果是AIX平台的, Linux平台可能會Segmentation fault

從這個結果來看,STRINGY並沒有像預期的那樣初始化為STRINGX

原因:

STRINGX和STRINGY是全 局靜態對象。STRINGY的初始化取決於STRINGX的初始化。兩者定義在不同的源文件中。

雖然C++語言規范規 定了同一個文件中這類對象的初始化順序(按照定義的順序),但並沒有規定在跨文件或者庫時這些對象的初始 化順序。

因此雖然模塊X.o先編譯, STRINGX仍可能會在STRINGY之後初始化, 這就形成了一個空的 STRINGY.

取決於編譯器和操作系統緩存中當前的值, STRINGY甚至可能包含了垃圾數據並導致程序運行時崩 潰。

解決方案:

為了解決這個問題,一些開發者將每個非局部靜態對象都移動到自己的函數中,並 聲明為靜態的。並讓這些函數返回這個靜態對象的引用, 然後按照自己期望的對象初始化順序來調用這些函數 .雖然這通常是個可移植的方法,但是這需要修改代碼。

XL C/C++編譯器可以使得這項工作變得簡單。你可以使用-qpriority或-qmkshrobj=priority(譯者注: linux上只有-qmkshrobj形式) 或 -Wm,-c選項來指定定義在不同文件或者庫中的靜態對象的初始化順序。這些 選項會給每個模塊賦予一個優先級值,然後根據該值來控制對象的初始化順序。

包含主函數main()的模塊通常優先級為0. 值越小表示優先級越高,在上面的例子中,可以在編譯X.o的時候 指定-qpriority=-100從而保證X.o中的對象在Y.o對象初始化之前初始化。

同樣的,如果你想把X.o創建到一個共享庫中,那麼可以在創建該庫的時候指定-qmkshrobj=-100。

即,你可以用下面的命令來編譯:

xlC -c -I./ -qpriority=-100 X.cpp -o X.o

xlC -c -I./ Y.cpp -o Y.o

xlC -o binary X.o Y.o

或者, 創建共享庫:

xlC -c -I./ X.cpp -o X.o

xlC -c -I./ Y.cpp -o Y.o

xlC -qmkshrobj=-100 -o libX.so X.o

xlC -o binary -btrl Y.o -L. -lX

這時執行程序就會得到如下結果:

./binary

CObjet::STRINGX [001]

STRINGY [001]

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