2009-06-17 110 views
2

我一直在嘗試從MSVC6切換到MSVC 2008時遇到內部編譯器錯誤。在大量工作註釋掉程序的不同部分後,我將錯誤追溯到兩行代碼兩個不同的CPP文件。這兩個CPP文件都可以編譯成功,但對某個錯誤是否顯示在其他文件中有影響。VS2008內部編譯器錯誤

這兩行都涉及實例化幾個複雜的嵌套模板。他們似乎也是應用程序中使用抽象類作爲模板參數之一的唯一地方。也就是說,我不確定這個問題涉及到抽象類還是模板,這只是我注意到的最明顯的事情。我甚至無法確定這些線是否有意義。下面是他們的樣子,雖然:

m_phDSAttributes = new SObjDict<RWCString, SIDataSource>(&RWCString::hash); 

所以我們已經有了SObjDict,了模板化的字典類,SIDataSource,一個抽象的接口,參數是指向RWCString的靜態成員函數。

我一直在玩一些代碼,並且偶爾會出現從一個CPP文件移動到另一個的錯誤(例如,我將一堆模板聲明從使用class更改爲typename),但是我找不到任何押韻或理由。

我不知道如何進一步調試這個問題。下面是編譯器輸出的確切錯誤(我的源文件的名稱已更改)。互聯網上沒有任何地方提及它。我非常渴望有關如何進行的任何建議。我不希望有人說「哦,你只需要做XYZ」,但是如何調試這種問題的指針將不勝感激。

1>d:\Dev\webapi.cpp : fatal error C1001: An internal error has occurred in the compiler. 
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 5905) 
+2

您是否向Microsoft投訴?該錯誤在編譯器中,即使您的代碼有問題,您也有權這樣做。無論如何,他們的編譯團隊可能會對問題是什麼有最好的想法。 – 2009-06-17 19:52:21

+0

@David:我們還沒有向MS發送錯誤報告。在查看與我們類似的其他錯誤報告(顯然p2symtab.c文件中存在很多錯誤)後,他們會拒絕任何不包含複製腳本的錯誤報告。我試圖將我們的bug降低爲簡單的repro腳本失敗。 – rmeador 2009-06-17 19:54:07

回答

2

我感覺稍差把答案在我的自己的問題,並接受它,但我想這是正確的事情做...我解決了我的問題,至少暫時。這個技巧似乎是禁用預編譯頭。我不知道爲什麼解決了問題,和這是非常不幸的,因爲我的受影響項目的構建時間從不到30秒到接近5分鐘,但至少我可以向前邁進......如果有人想出了一個更持久的解決方案,我會非常高興將其答案標記爲已接受。

-1

這通常發生在模板實例化中。不幸的是,它可能是由很多事情引起的,但是99%的代碼巧妙地調用了未定義的行爲。

0

將其分解爲更小的部分。我的第一個猜測是指向靜態函數的指針將成爲問題。你可以在構造函數中使用相同的參數來創建一個虛擬的非模板類嗎?如果您不在模板中使用抽象類,它會進行編譯嗎?

看起來像我送你在錯誤的方向上,繼2008年編譯罰款:

class thing { 
public: 
    static void hash(short sht) { 
    } 

    void hash(long lng) { 
    } 
}; 

class thing2 { 
public: 
    thing2(void (short)){} 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    thing2* t = new thing2(&thing::hash); 
    delete t; 
    return 0; 
} 

的原則仍然不過,刪除/替換複雜的元素,直到你已經編譯的代碼,你會知道是什麼導致了這個問題。

+0

功能指針是問題是我沒有考慮過的。我只注意到在RWCString中有2個稱爲hash()的函數。一個是靜態的,另一個是成員函數。他們有不同的簽名,雖然...有什麼辦法讓我手動消除他們的歧義,所以我可以肯定,這不會影響編譯器嗎? – rmeador 2009-06-17 20:04:47

+0

如果你有RWCString的控制權,那麼明顯改變它的名字,如果不是用兩個相似的函數創建一個虛擬類來檢查這是否是你的問題。我希望有些東西可以用函數指針來消除歧義(一個函數指針終究有簽名),如果不包含RWCString類並且有一個名爲hash2的靜態成員函數調用原始靜態函數...不是很優雅但會明確地做到這一點。 – Patrick 2009-06-17 20:47:51

1

假設p2symtab.c是(部分)符號表代碼是合理的選擇。這將立即解釋升級如何造成的;此代碼已被重寫。 (請記住VC6的255個字符長度警告?)

在這種情況下,符號表中沒有新條目,所以它可能在符號表中查找失敗。查看名稱查詢的上下文是否會影響結果會很有趣。舉例來說,如果你的代碼更改爲

typedef SObjDict<RWCString, SIDataSource> SObjDict_RWCString_SIDataSource; 
m_phDSAttributes = new SObjDict_RWCString_SIDataSource(&RWCString::hash); 

這將迫使其它符號表項將被創建的,SObjDict_RWCString_SIDataSource會發生什麼。此條目是模板實例化的一種符號鏈接。新名稱可以(並且必須)自行查找。

0

致命錯誤C1001:編譯器中發生內部錯誤。 1>(編譯器文件「F:\ DD \ vctools \編譯\ UTC的\ src \ P2 \ p2symtab.c

我也觀察到了同樣的錯誤,當我嘗試VS 2005的代碼構建我對VS 2008,但它發生直到我還沒有安裝VS 2008的服務包...

有你安裝了Service Pack ...我認爲這將解決您的問題....