1. 程式人生 > >g++裡使用常靜態成員變數的一個BUG

g++裡使用常靜態成員變數的一個BUG

    常靜態成員變數,即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)
{
}