g++裡使用常靜態成員變數的一個BUG
阿新 • • 發佈:2018-11-22
常靜態成員變數,即static Type const vName這樣的成員變數。以下程式碼,在g++中編譯時連結失敗,但是在VS2005和VS2008中編譯是沒有問題的。
#include<iostream> #include<vector> using namespace std; class CTest { public: static int const t = 3; void TestStaticConst(void); }; void CTest::TestStaticConst(void) { vector<int> ivec; vector<int>::iterator it = ivec.begin() + t; } int main(void) { }
連結失敗原因:
In function `CTest::TestStaticConst()':
btree.cpp:(.text+0x2e): undefined reference to `CTest::t'
collect2: 錯誤:ld 返回 1
但是如果把第15行,vector<int>::iterator it = ivec.begin() + t;,把最後的加法調換個順序,即修改成vector<int>::iterator it = t+ ivec.begin();,就可以編譯通過。
上述程式碼在VS2005和VS2008中編譯均是通過的,在G++中t在前和在後的結果不一樣,應該是個小BUG。
解決方法:
個人沒看到過其他人的程式中使用常靜態成員變數的,這個應該很少使用。
在類的聲明裡對常靜態成員變數初始化,即static int const t = 3,這種寫法是受限的。只能對整型(char/short/int/long)變數初始化,浮點型(float/double)或複合型別(如string)的常靜態成員變數是不能在類聲明裡初始化的。所以在使用常靜態成員變數時,標準做法是不要像上面那樣在聲明裡初始化,而是像普通static成員變數一樣,在類外初始化即可。
標準寫法見下,這樣在g++裡也可編譯通過。
#include<iostream>
#include<vector>
using namespace std;
class CTest
{
public:
static int const t;
void TestStaticConst(void);
};
int const CTest::t = 3;
void CTest::TestStaticConst(void)
{
vector<int> ivec;
vector<int>::iterator it = ivec.begin() + t;
}
int main(void)
{
}