C/C++編譯器錯誤代碼大全

編譯器錯誤 C2001  錯誤消息 
                          常數中有換行符
                          字符串常數不能繼續到第二行,除非進行下列操作: 
                         •用反斜槓結束第一行。
                         •用一個雙引號結束第一行上的字符串,並在下一行用另一個雙引號開始該字符串。
                          用 \n 結束第一行是不夠的。 
編譯器錯誤 C2002  錯誤消息
                          無效的寬字符常數
                          多字節字符常數是非法的。
                          通過檢查下面的可能原因進行修復
                         1.寬字符常數包含的字節比需要的多。
                         2.未包括標準頭文件 STDDEF.h。
                         3.寬字符不能與一般字符串連接。
                         4.寬字符常數之前必須是字符“L”: 
編譯器錯誤 C2003  錯誤消息
                          應輸入“defined id”
                          標識符必須跟在預處理器關鍵字之後。
編譯器錯誤 C2004  錯誤消息
                          應爲“defined(id)”
                          標識符必須出現在預處理器關鍵字之後的括號中。
                          也可能由於爲 Visual Studio .NET 2003 進行的編譯器一致性工作生成此錯誤:在預處理器指令中缺少括號。
                          如果預處理器指令缺少右括號,則編譯器將生成一個錯誤。
編譯器錯誤 C2005  錯誤消息
                          #line 應跟一個行號,卻找到“token”
                          #line 指令後面必須跟行號。
編譯器錯誤 C2006  錯誤消息
                          “directive”應輸入文件名,卻找到“token”
                           諸如 #include 或 #import 等指令需要文件名。若要解決該錯誤,請確保 token 是一個有效文件名。並且將該文件名放在雙引號或尖括號中。 
編譯器錯誤 C2007  錯誤消息
                          #define 語法
                          #define 後未出現標識符。若要解決該錯誤,請使用標識符。 
編譯器錯誤 C2008   錯誤消息
                          “character”: 宏定義中的意外
                           該字符緊跟在宏名之後。若要解決該錯誤,宏名之後必須有一個空格。 
編譯器錯誤 C2009   錯誤消息
                           宏形式“identifier”重複使用
                           宏定義的形參表多次使用該標識符。宏的參數列表中的標識符必須是唯一的。 
編譯器錯誤 C2010   錯誤消息 
                           “character”: 宏形參表中的意外
                            該字符在宏定義的形參表中使用不正確。移除該字符以解決該錯誤。
編譯器錯誤 C2011   錯誤消息 
                           “identifier”:“type”類型重定義
                            該標識符已定義爲 type 類型。如果多次將某個類型庫導入同一個文件,也可能生成 C2011。
編譯器錯誤 C2012   錯誤消息
                           在“<”之後缺少名稱
                           #include 指令缺少所需的文件名。
編譯器錯誤 C2013   錯誤消息
                           缺少“>”
                           #include 指令缺少右尖括號。添加右尖括號以解決該錯誤。 
編譯器錯誤 C2014   錯誤消息
                           預處理器命令必須作爲第一個非空白空間啓動
                           預處理器指令的 # 符號必須是非空白行上的第一個字符。 
編譯器錯誤 C2015   錯誤消息 
                           常數中的字符太多
                           一個字符常數包含的字符多於兩個。標準字符常數只能包含一個字符,長字符常數只能包含兩個字符。
                           轉義序列(如 \t)將被轉換爲單個字符。
                           當使用 Microsoft 擴展將字符常數轉換爲整數時,也可能發生 C2015。
編譯器錯誤 C2017   錯誤消息
                           非法的轉義序列
                           轉義序列(如 \t)出現在字符或字符串常數之外。
                           當 stringize 運算符與包括轉義序列的字符串一起使用時會發生 C2017。
編譯器錯誤 C2018   錯誤消息
                           未知字符“hexnumber”
                           源文件包含一個意外的 ASCII 字符,該字符由其十六進制數標識。若要解決該錯誤,請移除該字符。
編譯器錯誤 C2019   錯誤消息
                           應找到預處理器指令,卻找到“character”
                           該字符跟在 # 符號的後面,但它不是預處理器指令的第一個字母。 
編譯器錯誤 C2020   錯誤消息 
                          “member”:“class”成員重定義
                           從基類或結構繼承的成員被重定義。不能重定義繼承成員,除非它在基類中被聲明爲 virtual。
編譯器錯誤 C2021   錯誤消息
                           應輸入指數值,而非“character”
                           用作浮點常數的指數的字符是一個無效數字。確保使用的指數在範圍之內。 
編譯器錯誤 C2022   錯誤消息
                          “number”: 對字符來說太大
                           字符或字符串常數中跟在反斜槓 (\) 後面的八進制數字太大,不能表示字符。
編譯器錯誤 C2026   錯誤消息  
                           字符串太大,已截斷尾部字符
                           該字符串的長度超過了 16380 個單字節字符的**。
                           連接相鄰字符串之前,字符串的長度不能超過 16380 個單字節字符。
                           大約爲此長度的一半的 Unicode 字符串也會生成此錯誤。
編譯器錯誤 C2027   錯誤消息 
                           使用了未定義類型“type”
                           類型只有經過定義才能使用。若要解決該錯誤,請確保在引用類型前已對其進行了完全定義。
                           有可能聲明一個指向已聲明但未定義的類型的指針。但是 Visual C++ 不允許引用未定義的類型。
編譯器錯誤 C2028   錯誤消息 
                           結構/聯合成員必須在結構/聯合中
                           結構或聯合成員必須在結構或聯合內部聲明。
編譯器錯誤 C2030   錯誤消息 
                           “identifier”: 結構/聯合成員重定義
                            結構或聯合將同一標識符用於多個成員。
編譯器錯誤 C2032   錯誤消息 
                           “identifier”: 函數不能是結構/聯合“structorunion”的成員
                           該結構或聯合中的一個成員函數在 C++ 中允許使用而在 C 中卻不允許。若要解決該錯誤,請編譯爲 C++ 程序或移除該成員函數。 
編譯器錯誤 C2033   錯誤消息 
                           “identifier”: 位域不能有間接尋址
                           該位域被聲明爲指針,這是不允許的。
編譯器錯誤 C2034   錯誤消息 
                           “identifier”: 位域類型對於位數太小
                            該位域聲明中位的數目超過了基類型的大小。 
編譯器錯誤 C2036   錯誤消息 
                           “identifier”: 未知的大小
                            對 identifier 的操作需要數據對象的大小,而該大小無法確定。 
編譯器錯誤 C2039   錯誤消息 
                           “identifier1”: 不是“identifier2”的成員
                           該代碼錯誤調用或引用了結構、類或聯合的成員。
編譯器錯誤 C2040   錯誤消息 
                           “operator”:“identifier1”與“identifier2”的間接尋址級別不同
                           涉及該運算符的表達式具有不一致的間接尋址級別。
                           如果兩個操作數都是算術的或都是非算術的(如數組或指針),則不用更改就可使用它們。如果一個操作數是算術的,而另一個不是,則算術運算符將轉換爲非算術類型。
編譯器錯誤 C2041   錯誤消息 
                           非法的數字“character”(用於基“number”)
                                        指定的字符不是基(如八進制或十六進制)的有效數字。
編譯器錯誤 C2042   錯誤消息 
                           signed/unsigned 關鍵字互相排斥
                           在單個聲明中使用關鍵字 signed 和 unsigned。 
編譯器錯誤 C2043   錯誤消息 
                           非法 break
                                         break 僅在 do、for、while 或 switch 語句中合法。
編譯器錯誤 C2044   錯誤消息 
                           非法 continue
                                         continue 僅在 do、for 或 while 語句中合法。
編譯器錯誤 C2045   錯誤消息 
                           “identifier”: 標籤重定義
                            該標籤出現在同一函數中的多條語句之前。 
編譯器錯誤 C2046   錯誤消息 
                           非法的 case
                                       關鍵字 case 只能出現在 switch 語句中。
編譯器錯誤 C2047   錯誤消息 
                           非法的 default
                                        關鍵字 default 僅能出現在 switch 語句中。
編譯器錯誤 C2048   錯誤消息 
                           默認值多於一個
                           switch 語句包含多個 default 標籤。刪除其中一個 default 標籤可解決該錯誤。 
編譯器錯誤 C2050   錯誤消息 
                           switch 表達式不是整型
                           switch 表達式計算結果爲一個非整數值。若要解決該錯誤,請在 switch 語句中只使用整數值。 
編譯器錯誤 C2051   錯誤消息 
                           case 表達式不是常數
                           Case 表達式必須是整數常數。 
編譯器錯誤 C2052   錯誤消息 
                           “type”: 非法的 case 表達式類型
                           Case 表達式必須是整數常數。
編譯器錯誤 C2053   錯誤消息 
                           “identifier”: 寬字符串不匹配
                           寬字符串被分配給了一個不兼容的類型。 
編譯器錯誤 C2054   錯誤消息 
                           在“identifier”之後應輸入“(”
                           該函數標識符用在需要尾部括號的上下文中。
                           導致該錯誤的可能原因是省略了複雜初始化上的等號 (=)。
編譯器錯誤 C2055   錯誤消息
                           應輸入形參表,而不是類型表
                           函數定義包含參數類型列表而不包含形參表。ANSI C 需要命名的形參,除非它們是 void 或是省略號 (...)。 
編譯器錯誤 C2056   錯誤消息 
                           非法表達式
                           表達式因前一個錯誤而無效。
編譯器錯誤 C2057   錯誤消息 
                           應輸入常數表達式
                           上下文要求常數表達式,即其值在編譯時已知的表達式。
編譯器錯誤 C2058   錯誤消息 
                           常數表達式不是整型
                           該上下文需要整數常數表達式。
編譯器錯誤 C2059   錯誤消息 
                           語法錯誤 :“token”
                           該標記導致語法錯誤。
                           若要確定原因,則不僅要檢查在錯誤信息中列出的行,還要檢查該行上面的行。下面的示例對聲明 j 的行生成了錯誤信息,而該錯誤的真正源卻出現在其上面的行中。
                           如果對行的檢查沒有獲得有關可能出現的問題的任何線索,則嘗試註釋掉在錯誤信息中列出的行以及可能出現在該行上面的若干行。
                           如果該錯誤信息在緊跟 typedef 變量的符號上出現,則檢查該變量是否已在源代碼中定義。
                           如果符號沒有計算出任何結果(在使用 /Dsymbol= 編譯時可能發生),可能會導致 C2059。
                          可能收到 C2059 的另一個特定原因是編譯在函數的默認參數中指定了結構的應用程序。參數的默認值必須是一個表達式。初始值設定項列表(如用於初始化結構的初始值設定項列 表)不是表達式。其解決方法是定義一個執行所需初始化的構造函數。
編譯器錯誤 C2060   錯誤消息 
                           語法錯誤 : 遇到文件結束
                           至少還需要一個標記。
編譯器錯誤 C2061   錯誤消息 
                           語法錯誤: 標識符“identifier”
                           編譯器發現了不應在此出現的標識符。請確保在使用 identifier 之前對其進行聲明。
                          初始值設定項可能括在了括號中。爲避免該問題,請將聲明符括在括號中或使其成爲 typedef。
                           在編譯器將表達式作爲類模板參數檢測時也可能導致此錯誤;使用 typename 告訴編譯器它是一個類型。
編譯器錯誤 C2062   錯誤消息 
                           意外的類型“type”
                           編譯器不需要類型名稱。
                           編譯器處理構造函數的參數列表中未定義類型的方式也可能導致 C2062。如果編譯器遇到未定義的(拼錯了嗎?)類型,則它假定構造函數是一個表達式,併發出 C2062。若要解決此錯誤,請只使用構造函數參數列表中的定義類型。
編譯器錯誤 C2063   錯誤消息 
                           “identifier”: 不是函數
                           該標識符用作函數,但未聲明爲函數。 
編譯器錯誤 C2064   錯誤消息 
                           項不會計算爲接受“number”個參數的函數
                           通過表達式調用了函數。該表達式未計算爲函數指針。
編譯器錯誤 C2065   錯誤消息 
                           “identifier”: 未聲明的標識符
                           在可使用變量的類型前必須在聲明中指定它。在可以使用函數前必須在聲明或原型中指定該函數使用的參數。
                           可能的原因:
                          1.您正在用 C 運行庫的調試版本進行編譯,在 for 循環中聲明標準 C++ 庫迭代器變量,然後嘗試在 for 循環範圍外使用該迭代器變量。 用 C 運行庫的調試版本編譯標準 C++ 庫代碼暗指使用 /Zc:forScope。有關更多信息,請參見調試迭代器支持。
                          2.可能正在調用當前不受生成環境支持的 SDK 頭文件中的函數。
                          3.省略必要的包含文件,尤其是在定義 VC_EXTRALEAN、WIN32_LEAN_AND_MEAN 或 WIN32_EXTRA_LEAN 時。這些符號從 windows.h 和 afxv_w32.h 中排除了一些頭文件以加快編譯。(在 windows.h 和 afxv_w32.h 中查找排除的頭文件的最新說明。)
                          4.標識符名拼寫錯誤。
                          5.標識符使用了錯誤的大小寫字母。
                          6.字符串常數的後面缺少右引號。
                          7.命名空間範圍不正確。例如,若要解析 ANSI C++ 標準庫函數和運算符,則必須用 using 指令指定 std 命名空間。下面的示例未能編譯,因爲 using 指令被註釋掉,並且在 std 命名空間中定義了 cout: 
編譯器錯誤 C2066   錯誤消息 
                           轉換到函數類型是非法的
                           在 ANSI C 中,函數指針和數據指針間的轉換是非法的。
編譯器錯誤 C2067   錯誤消息 
                           轉換到數組類型是非法的
                           對象被轉換成了數組類型。
編譯器錯誤 C2069   錯誤消息 
                           “void”項到非“void”項的強制轉換
                           類型 void 不能轉換成任何其他類型。
編譯器錯誤 C2070   錯誤消息 
                           “type”: 非法的 sizeof 操作數
                           sizeof 運算符需要一個表達式或類型名稱。 
編譯器錯誤 C2071   錯誤消息 
                           “identifier”: 非法的存儲類
                           聲明 identifier 所用的存儲類無效。 
編譯器錯誤 C2072   錯誤消息 
                          “identifier”: 函數的初始化
                           錯誤指定了函數初始值設定項。
編譯器錯誤 C2073   錯誤消息 
                          “identifier”: 部分初始化數組的元素必須有默認構造函數
                           爲用戶定義的類型或常數的數組指定的初始值設定項太少。如果沒有爲數組成員指定明確的初始值設定項及其對應的構造函數,則必須提供默認的構造函數。
編譯器錯誤 C2074   錯誤消息 
                          “identifier”:“class-key”初始化需要大括號
                           在指定的類、結構或聯合初始值設定項兩邊沒有大括號。
編譯器錯誤 C2075   錯誤消息 
                           “identifier”: 數組初始化需要大括號
                           在指定的數組初始值設定項兩邊沒有大括號。 
編譯器錯誤 C2077   錯誤消息 
                           非標量字段初始值設定項“identifier”
                           試圖用非標量(結構、聯合、數組或類)初始化位域。使用整數值或浮點值。
編譯器錯誤 C2078   錯誤消息 
                           初始值設定項太多
                           初始值設定項的數目超過了要初始化的對象數。
編譯器錯誤 C2079   錯誤消息 
                          “identifier”使用未定義的類/結構/聯合“name”
                           指定的標識符是一個未定義的類、結構或聯合。
                           初始化匿名聯合時,可能會導致此錯誤。
編譯器錯誤 C2081   錯誤消息 
                           “identifier”: 形參表中的名稱非法
                           標識符導致語法錯誤。
                           此錯誤可能是由使用形參表的舊形式導致的。必須在形參表中指定形參的類型。
編譯器錯誤 C2082   錯誤消息 
                           形參“identifier”的重定義
                           在函數體中重新聲明瞭函數的形參。若要解決該錯誤,請移除該重定義。 
編譯器錯誤 C2083   錯誤消息 
                           結構/聯合比較非法
                           結構或聯合直接與另一個用戶定義的類型進行比較。這是不允許的,除非已經定義了比較運算符或者存在到標量類型的轉換。
編譯器錯誤 C2084   錯誤消息 
                           函數“function”已有主體
                           函數已經定義。
                           在以前的 Visual C++ 版本中, 
                           •編譯器將接受解析爲同一實際類型的多個模板的專用化,儘管附加的定義將永遠不可用。現在編譯器將檢測這些多重定義。 
                           •__int32 和 int 已被視爲單獨的類型。編譯器現在將 __int32 作爲 int 的同義詞處理。這意味着,如果函數同時在 __int32 和 int 上重載,編譯器將檢測多個定義,並提供一個錯誤。
編譯器錯誤 C2085   錯誤消息 
                          “identifier”: 不在形參表中
                           該標識符在函數定義中聲明而未在形參表中聲明。(僅用於 ANSI C)
編譯器錯誤 C2086   錯誤消息
                           “identifier”: 重定義
                            多次定義了該標識符,或者後面的聲明與前一個不同。 
                           C2086 也可能是增量編譯引用的 C# 程序集的結果。重新生成該 C# 程序集以解決此錯誤。
編譯器錯誤 C2087   錯誤消息 
                          “identifier”: 缺少下標
                           具有多個下標的數組的定義缺少大於 1 的維度的下標值。
編譯器錯誤 C2088   錯誤消息 
                           “operator”: 對於“class-key”非法
                           沒有爲結構或聯合定義該運算符。該錯誤只對 C 代碼有效。
編譯器錯誤 C2089   錯誤消息 
                          “identifier”:“class-key”太大
                           指定的結構或聯合超過 4GB 的**。
編譯器錯誤 C2090   錯誤消息 
                           函數返回數組
                           函數不能返回數組。請返回指向數組的指針。 
編譯器錯誤 C2091   錯誤消息 
                           函數返回函數
                           函數不能返回函數。請返回指向函數的指針。
編譯器錯誤 C2092   錯誤消息 
                          “array name”數組元素類型不能是函數
                           不允許使用函數數組。請使用指向函數的指針的數組。
編譯器錯誤 C2093   錯誤消息 
                          “variable1”: 無法使用自動變量“variable2”的地址初始化
                           在用 /Za 編譯時,程序試圖將自動變量的地址用作初始值設定項。
編譯器錯誤 C2094   錯誤消息 
                           標籤“identifier”未定義
                           goto 語句使用的標籤在函數中不存在。 
編譯器錯誤 C2095   錯誤消息 
                          “function”: 實參具有類型“void”:“number”參數
                           傳遞給函數的參數爲 void 類型,這是不允許的。請改爲使用指向 void 的指針 (void *)。
                           number 指示哪一個參數爲 void。
編譯器錯誤 C2097   錯誤消息 
                           非法的初始化
                          通過檢查下面的可能原因進行修復
                          1.使用非常數值初始化變量。
                          2.用長地址初始化短地址。
                          3.在用 /Za 編譯時,用非常數表達式初始化局部結構、聯合或數組。
                          4.用包含逗號運算符的表達式初始化。
                          5.用既非常數又非符號的表達式初始化。
編譯器錯誤 C2099   錯誤消息 
                           初始值設定項不是常數
                           此錯誤只由 C 編譯器發出,而且只對非自動變量發生。編譯器在程序的開頭對非自動變量進行初始化,並且用於對這些變量進行初始化的值必須是常數。
                           由於編譯時與運行時的浮點精度環境設置(有關更多信息,請參見 _controlfp_s)可能不同,因此,編譯器無法在 /fp:strict 下對表達式執行常數合併。在這種情況下,也可能發生 C2099。
                           當常數合併失敗時,編譯器調用動態初始化,這在 C 中是不允許的。
                           要解決此錯誤,請將模塊編譯爲 .cpp 文件或對表達式進行簡化。 

====================================================================================================================================

1.

事件:在非MFC環境中使用CStdioFile時,欲#include<afx.h>,提示鏈接錯誤如下

錯誤 1 error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) 已經在 libcpmtd.lib(newaop.obj) 中定義 D:\Code_CSharp\Code_Airport\Code_Airport\uafxcwd.lib(afxmem.obj) Code_Airport

原因:搜了下可能是MFC相關類庫與C++的類庫include的順序不對,然後造成某些符號提示重定義。

解決方法:將MFC的相關類庫在程序最開始的位置包含。此處,我將<afx.h>放在最開始的位置包含,重編譯即成功。


2. 

事件:在c#中想調用dll提示如下錯誤:“無法加載dll  異常來自HRESULT:0X8007007E”

原因:經過百度,瞭解到應該是我想import的dll還有其他依賴的dll,經過將其依賴的opencvdll打包放一起之後,該錯誤提示消失。


3.

事件:這是一系列常見錯誤了,老出現,就是各種windows自帶的類型,如“CString,CRect等提示找不到符號”。

原因:其實是stdafx.h沒有成功include,修改下就好。


4.

事件:VS2010中設置的斷點無效:“當前不會命中斷點,還沒有爲該文檔加載任何符號”。

原因:折騰了一陣,其實問題主要出在沒有生成調試信息。比較弱的錯誤是在Release下運行,肯定進不了斷點,改成Debug就行;當然非得在Release下設置斷點的話,可以通過下面的解決方法來搞。

解決方法:
(1)項目-〉屬性-〉配置屬性-〉C/C++-〉常規-〉調試信息格式,這裏不能爲“禁用”。
(2)項目-〉屬性-〉配置屬性-〉鏈接器-〉調試-〉生成調試信息,這裏設爲“是”。

5.

事件:VS2010安裝時由於想省時間因此沒有裝MSDN,現在又想裝MSDN。

解決方法:打開VS工作界面,幫助->管理幫助設置,在彈出的選擇文件對話框中選擇你當前需要將MSDN安裝到哪裏/路徑;選擇當前MSDN的案卷源文件,一般在你的ISO文件的ProductDocumentation目錄下的HelpContentSetup.msha文件即可,以後程序會自動引導安裝;同時,在安裝之前,你還可以選擇安裝哪些幫助文檔。


6.

事件:應用程序無法啓動,因爲應用程序的並行配置不正確。

原因:win7的64位系統缺少x86庫文件。

解決方法:安裝vcredist_x86


7.

事件:“mt.exe : general error c101008a: Failed to save the updated manifest to the file "./Debug/TransSliderControl.exe.embed.manifest"”vs編譯過程中給出如上提示。

解決方法:清理解決方案,再重新生成。


8.

事件:CLR無法從COM 上下文0x645e18 轉換爲COM上下文0x645f88,這種狀態已持續60秒2010-01-20 09:08異常信息:CLR無法從COM 上下文0x645e18 轉換爲COM上下文0x645f88,這種狀態已持續60秒。擁有目標上下文/單元的線程很有可能執行的是非泵式等待或者在不發送 Windows 消息的情況下處理一個運行時間非常長的操作.這種情況通常會影響到性能,甚至可能導致應用程序不響應或者使用的內存隨時間不斷累積。要避免此問題,所有單線程單元(STA)線程都應使用泵式等待基元(如 CoWaitForMultipleHandles),並在運行時間很長的操作過程中定期發送消息


解決方法: 在Debug -> Exceptions -> Managed Debug Assistants裏 去掉ContextSwitchDeadlock一項前面的鉤。
在調試(菜單)-->異常--> Managed Debug Assistants裏 去掉ContextSwitchDeadlock一項前面的鉤。

9.

事件:可訪問性不一致: 字段類型“a”比字段“b"的訪問性低 
解決辦法:在你的結構體或者是類,聲明一下訪問權限,修改成public,這樣就不會有這些問題的存在。

====================================================================================================================================

1、error C2065: “IDD_DIALOG1” : 未聲明的標識符

編譯時提示error C2065: “IDD_DIALOG1” : 未聲明的標識符

錯誤的可能原因及解決方法如下:
  
1.出錯文件中沒有包含資源文件ID聲明的resource.h文件。在出錯文件中加入#include “resource.h”語句。

2.工程附件包含目錄的路徑下沒有resource.h文件。修改路徑即可。

3.工程所在文件夾下存在resource.h文件,但其中沒有資源ID的定義, 導致真正的resource.h沒有包含進去,刪除之。一個解決方案裏面有多個工程,可能會把所有資源ID的聲明放到一個文件中。在各個工程中實現對話框 功能的文件中,只需包含該文件即可。但是,當新增某個資源以後,工程中會自動生成一個resource.h(不知道爲什麼會這樣),而不是在已有的 resource.h文件中添加ID的定義。由於工程編譯的時候先從本地搜索頭文件,會包含了自動生成的頭文件,於是出現了上述錯誤。

注意:如果是智能設備程序出現此錯誤,應該確保resourceppc.h和Resourceppc.h中都有相同的宏定義#define IDD_DIALOG1 XXX,並且在dialog.cpp中包含資源頭文件resourceppc.h

=====================================================================================================================================

2、error C2471: 無法更新程序數據庫 ,fatal error C1083: 無法打開程序數據庫文件

error C2471: 無法更新程序數據庫“c:documents and settings.......debugvc90.pdb”

fatal error C1083: 無法打開程序數據庫文件:“c:documents and settings........debugvc90.pdb”: No such file or directory ....

解決方法:

修改一下設置,就可以解決C2471:
CC++ | General | Debug Information format | C7 Compatible (/Z7)
CC++ | Code Generation | Enable String Pooling | Yes (/GF)
Linker | General Debug Info | Yes (/DEBUG)

或者把在debug文件夾下的.pdb文件給刪除了,f5一下就行了

=====================================================================================================================================

3、error無法打開預編譯頭文件的解決方法及預編譯頭原理

1。用VC.NET編輯程序,按Ctrl+F7,出現下列錯誤:
fatal error C1083: 無法打開預編譯頭文件:“Debug/UGFace.pch”: No such file or directory
解決方法:修改:項目->屬性->C/C++ ->預編譯頭->不使用預編譯頭 即可。


2。學用Visual C++ 6.0的第一個例程就讓我出了錯.用嚮導生成第一個基於對話框的Project之後,當我按照書上的源程序一個字一個字地輸進去之後,始終有一個錯誤:
fatal error C1010: unexpected end of file while looking for precompiled header directive.找了無數次之後,我決定把嚮導生成的包括頭文件的語句:include"StdAfx.h"保留(而這之前我是把它刪掉了的,因爲書 上的例子沒有這句.)咦,這下就對了.這是爲什麼呢?我百思不得其解。
來 到我的VC源代碼目錄,我注意到每個Project下面的DEBUG文件夾都特別大,而且一個擴展名爲 .pch的文件佔去了絕大部分,我刪掉之好像對程序編譯運行沒有什麼影響。於是抱着對.pch文件的好奇,我在網上搜到了我疑惑之處的解答。這就是 VC++6.0給我們帶來的:預編譯頭文件。預編譯頭文件(一般擴展名爲.PCH),是把一個工程中較穩定的代碼預先編譯好放在一個文件(.PCH)裏。 這些預先編譯好的代碼可以是任何的C/C++代碼,甚至可以是inline函數,只是它們在整個工程中是較爲穩定的,即在工程開發過程中不會經常被修改的 代碼。
爲什麼需要預編譯頭文件?
一 言以蔽之:提高編譯速度.一般地,編譯器以文件爲單位編譯。如果修改了一工程中的一個文件則所有文件都要重新編譯,包括頭文件裏的所有東西 (eg.Macro宏,Preprocessor預處理),而VC程序中,這些頭文件中所包括的東西往往是非常大的,編譯之將佔很長的時間。但它們又不常 被修改,是較穩定的,爲單獨的一個小文件而重新編譯整個工程的所有文件導致編譯效率下降,因此引入了.PCH文件。
如何使用預編譯頭文件以提高編譯速度?
要 使用預編譯頭文件,必須指定一個頭文件(.H),它包含我們不會經常修改的代碼和其他的頭文件,然後用這個頭文件來生成一個預編譯頭文件 (.PCH),VC默認的頭文件就是StdAfx.h,因爲頭文件是不能編譯的,所以我們還需要一個.CPP文件來作橋樑,VC默認的文件爲 StdAfx.cpp,這個文件裏只有一句代碼就是:#include "StdAfx.h"。接下來要用它生成.PCH文件,涉及到幾個重要的預編譯指令:/Yu,/Yc,/Yx,/Fp。簡單地說,/Yc是用來生 成.PCH文件的編譯開關。
在Project->setting->C/C++的Category裏的Precompiled Header,然後在左邊的樹形視圖中選擇用來編譯生成.PCH文件的.CPP文件(默認即StdAfx.cpp),
你 就可以看到/Yc這個開關,它表示這個文件編譯了以後是否生成.PCH文件(可能/Yc的c表示create)。/Fp指令指定生成的.PCH文件的名字 及路徑(可能/Fp的p代表path)。/Yu的u即use,工程中只要包括了.H文件的文件都會有這個/Yu指令。如果選擇自動 Automatic...的話則原來爲/Yc的地方就換成了/Yx指令。如果選擇自動,則每次編譯時編譯器會看以前有沒有生成過.PCH文件,有則不現生 成否則就再次編譯產生.PCH文件。
注意:
A, 實際上,由Appzard項目嚮導生成的默認的頭文件及CPP文件StdAfx.h和StdAfx.cpp可以是任何名字的.原因很簡單。但如果你要這樣 做就要記得修改相應的Project->setting...下的幾個預編譯指(/Yc,/Yu,/Yx,/Fp)的參數。
B. 在任何一個包括了將要預編譯的頭文件而使用了.PCH文件的工程文件的開頭,一定必須要是在最開頭,你要包含那個指定生成.PCH文件的.H文件(通 過.CPP文件包括,默認爲StdAfx.cpp),如果沒包括將產生我最開頭產生的錯誤.如果不是在最開頭包括將產生讓你意想不到的莫名其妙錯誤,如若 不信,盍爲試之?
C.預編譯文件.PCH生成之很耗時間,而且生成之後它也很佔磁盤空間,常在5-6M,注意項目完成之後及時清理無用的.PCH文件以節約磁盤空間。
D.如果丟了或刪了.PCH文件而以後要再修改工程文件時,可將指定的/Yc的.CPP文件(默認爲StdAfx.cpp)重新編譯一次即可再次生成.PCH文件,不用傻傻的按F7或Rebuild All


以 前還碰到過另外一種情況:新建一個工程,隨便找一個cpp文件,按ctrl+f7系統將會提示:fatal error C1083: 無法打開預編譯的頭文件:”Debug/xxx.pch”: No such file or directory(其中xxx是工程的名字)這種情況也是一樣的原因,爲vc的stdafx.h頭文件未編譯所致。也可以這樣解決:先F7,編譯後再 ctrf+f7。

注意:VS智能設備程序(如WM5)預編譯頭文件爲stdafx.h。更改設置在項目->XXXX屬性->配置屬性->C/C++->預編譯頭 的右側第一項。
=====================================================================================================================================
4、
error:無法執行添加/移除操作,因爲代碼元素是隻讀的

vc2005error:無法執行添加/移除操作,因爲代碼元素是隻讀的
出現這種現象,多數是因爲你的工程所在文件夾的屬性設置爲了“只讀”,你可以關閉解決方案,然後重新打開,就可以了,如果以後不想出現這樣的情況,把工程所在的文件夾屬性中的“只讀”去掉,就可以了。

解決方案:
1、重啓VS2005

2、查看.h和.cpp文件的屬性,有可能是隻讀的,修改屬性後就可以了
3、打開Resource.h文件看看 一看就知道了 有些定義重複了 可以手動改掉 保存 編輯器重新加載

4、把你要添加事件的對話框相應的類文件(*.h和*.cpp)給關了就可以了
5、關閉解決方案,刪除.ncb文件重新添加即可

6、實在不行就手動添加消息處理

在BEGIN_MESSAGE_MAP(。。。)
//這裏要刪掉你原先已經增加過的消息隱射函數
END_MESSAGE_MAP()

=====================================================================================================================================

5、程序運行出現-1.#IND,1.#INF


C/C++程序運行有時候會出現-1.#IND,1.#INF,在調試的時候輸出除數爲0得出的結果,

INF就是infinite,就是無窮大的意思

IND可能表示很小,不確定

//////////////////////////////////////////////////////////

使用類似於pow, exp等等函數時常會產生一個無效數字1.#IND00,在VC下可以通過與一個確定數字比較大小來判斷是否產生了無效數字,但這個方法在DEV-CPP下卻是行不通的。

其實解決辦法很簡單,使用   float.h中一個函數_isnan即可:

int _isnan(double x);  
  
當x是一個無效值(NaN, Not a Number) 時,返回非零值
否則返回0

======================================================================================================================================

6、LINK : 上一個增量鏈接沒有生成它;正在執行完全鏈接

代碼

#include"iostream"
using namespace std;
int main()
{
cout<<"123";
return 0;
}
LINK : 沒有找到 D:Visual Studio 2008ProjectstestDebugtest.exe 或上一個增量鏈接沒有生成它;正在執行完全鏈接

這個不是什麼錯誤,現在的VS2003,2005,2009有增量編譯功能,就是如果你的代碼改動了,他們是不完全重新編譯整個代碼的,而是隻編譯你所更改的部分。

出現這個提示,
1.你是第一次進行編譯,這時當然沒有生成過可執行文件,也就無法增量鏈接了。
2.你上一次編譯的時候有錯誤,沒有生成可執行文件。
=====================================================================================================================================
7、
CListCtrl的NM_RCLICK消息編譯錯誤、reinterpret_cast

在對話框中類中添加對CListCtrl控件右鍵處理的時候出現如下錯誤:

error C2440: 'reinterpret_cast' : cannot convert from 'NMHDR *' to 'NMITEMACTIVATE' Conversion requires a constructor or user-defined-conversion operator, which can't be used by const_cast or reinterpret_cast

需要把:LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<NMITEMACTIVATE>(pNMHDR);
; 改爲: LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
參考:http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=339678

=====================================================================================================================================

8、無法解析的外部符號 _WinMain,該符號在函數 ___tmainCRTStartup 中被引用

一,問題描述
MSVCRTD.lib(crtexew.obj) : error LNK2019: 無法解析的外部符號_WinMain@16,該符號在函數 ___tmainCRTStartup 中被引用
Debugjk.exe : fatal error LNK1120: 1 個無法解析的外部命令

error LNK2001: unresolved external symbol_WinMain@16
debug/main.exe:fatal error LNK 1120:1 unresolved externals
error executing link.exe;

二,產生這個問題可能的原因
產生這個問題的真正原因是c語言運行時找不到適當的程序入口函數,一般情況下,如果是windows程序,那麼WinMain是入口函數,如果是dos控制檯程序,那麼main是入口函數,而如果入口函數指定不當,很顯然c語言運行時找不到配合函數,它就會報告錯誤。

可能:

1, 你用vc建了一個控制檯程序,它的入口函數應該是main, 而你使用了WinMain.

2. 你用vc打開了一個.c/.cpp 文件,然後直接編譯這個文件,這個文件中使用了WinMian而不是main作爲入口函數。vc這時的默認設置是針對控制檯程序的。

3.根本就沒有WinMain或Main函數。

三, 解決方法
1.進入project->setting->c/c++, 在category中選擇preprocessor,在processor definitions中刪除_CONSOLE, 添加_WINDOWS

2.進入project->setting->Link, 在Project options中將 /subsystem:console改爲/subsystem:windows.

3.保存設置,Rebuild All.

四,VS2008中的設置

1.菜單中選擇 Project->Properties, 彈出Property Pages窗口

2.在左邊欄中依次選擇:Configuration Properties->C/C++->Preprocessor,然後在右邊欄的Preprocessor Definitions對應的項中刪除_CONSOLE, 添加_WINDOWS.

3.在左邊欄中依次選擇:Configuration Properties->Linker->System,然後在右邊欄的SubSystem對應的項改爲Windows(/SUBSYSTEM:WINDOWS)

4.Rebuild All. Ok ?

=====================================================================================================================================

9、fatal error LNK1112: 模塊計算機類型“ARM”與目標計算機類型“X86”衝突

fatal error LNK1112: 模塊計算機類型“ARM”與目標計算機類型“X86”衝突

解決方法:鏈接器 -> 命令行 -> 附加選項, 添加 /MACHINE:ARM /MACHINE:THUMB

 

fatal error LNK1112: 模塊計算機類型“THUMB”與目標計算機類型“ARM”衝突

解決方法:

第1種:鏈接器 -> 命令行 -> 附加選項, 添加 /MACHINE:THUMB

第2種:新建項目時,在"平臺"->"選擇要添加到當前項目中的 Platform SDK。"中,把"已安裝的 SDK"全部添加到"選定的 SDK"

如果是直接使用已經創建好的工程,那麼第一種方法就可以解決了,實在不行,就只有採用第二種辦法從頭解決了 。


=====================================================================================================================================

10、error c3872: “0x3000”: 此字符不允許在標識符中使用

例如friend ostream& operator<<(ostream& out,const Chain<T>& x );
出錯error c3872: “0x3000”: 此字符不允許在標識符中使用

解決方法:

0x3000是漢語的空格,也就是全角空格,相當於一個漢字,但你又看不見它。

像逗號,有半角(,)和全角(,)之分的,其實空格也有。
0x3000是全角的空格,0x20是半角的空格。

你最好把這個語句的後面空白部分都刪除掉,並檢查是否有中文標點存在

====================================================================================================================================

11、0x????處未處理的異常:0xC0000005

    使用VC編碼的時候經常會出現“Test.exe 中的 0x00414030 處未處理的異常: 0xC0000005: 寫入位置 0xfeeefeee 時發生訪問衝突 。

     出現0xC0000005的原因一般都是沒有分配內存 或者 內存無效 所致,

例如:

#include "stdafx.h"
#include <string>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

string * s = NULL;
s = new string();
delete s;

if (s != NULL)
{
   *s = "TEST"; //這步操作將引起異常。
}

return 0;
}

雖然s已經被delete了,但是s的值並不爲NULL,if語句的判斷將失效,這是新手常見的一個錯誤!

爲了防止這個錯誤可以自己定義一個宏來處理delete。

#define _DELETE(obj) if (obj != NULL) {delete obj , obj = NULL;}

使用這個宏可以防止類似錯誤出現。


=====================================================================================================================================

12、沒有找到MFC80UD.DLL,因此這個程序未能啓動.重新安裝應用程序可能會修復此問題

在vs2005 sp1中文版中,在“解決方案資源管理器”中的項目上右擊,選擇“屬性”,找到“配置屬性”中的“鏈接器”,然後找到“清單文件”,在右邊的屬性框中,默認“生成清單”項爲“是”,選 把“是”改成“否”,運行之,出錯,然後再把否改回來,OK

其他:

1)如果不選"系統菜單""關於菜單"就不會有這個問題!
2)如果在"工程屬性->配置屬性->常規->字符集""使用多字節字符集"也不會出這個問題!
3)好像是刪除所有的中間文件,(具體一點說,就是刪除."(工程文件)"Debug裏的文件和.ncb),"重新生成解決方案文件...",可能可以.
4clean關閉vs,打開rebuild應該就可以了,我的很少遇到。遇到之後這樣就解決了。不行就多試幾次。
5linker-manifest-file-Generate Manifest: Yes
6Manifest搞的鬼,然後修改項目屬性,清單工具中的輸入輸出把嵌入清單文件選否.然後編譯,鏈接運行,成功

debug---動態使用dll
release---靜態使用dll

debug狀態下使用,會時不時出這個問題;
release狀態下使用,不會出現這個問題。


=====================================================================================================================================

13、沒有找到MFC80D.DLL或msvcr80d.dll的解決方法

   解決方案:

在編輯狀態下,點項目菜單 -> XXX屬性頁 -> 配置屬性 -> 清單工具,將右面的使用FAT32解決辦法選爲即可。簡單地,其實把程序目錄下的Debug目錄整個刪掉,再讓VS全部重新生成文件也能解決這個問題,只是可能再犯。

沒有找到MFC80D.DLL的解決方法。問題出現在程 序運行清單上,默認是"嵌入清單",清單文件是"$(IntDir$(TargetFileName).embed.manifest"。調試程序運行 時,不知道爲什麼卻定位不到這個文件,我們如果手動把"程序名.embed.manifest"改爲"程序名.manifest",調試程序即可定位到。

其他

方法一:
在C:Program FilesMicrosoft Visual Studio 8VCredi
stDebug_NonRedistx86Microsoft.VC80.DebugCRT 下找到了下列文件:

msvcm80d.dll
msvcp80d.dll
msvcr80d.dll
Microsoft.VC80.DebugCRT.manifest

把這幾個文件拷貝到目標機器上,與運行程序同一文件夾或放到system32下,就可以運行那個程序了。

方法二:
修改編譯選項,將/MD或/MDd 改爲 /MT或/MTd,這樣就實現了對VC運行時庫的靜態鏈接,在運行時就不再需要VC的dll了。


=====================================================================================================================================

14、fatal error LNK1181: 無法打開輸入文件“..filename.lib”

鏈接器未能找到 filename,因爲該文件不存在或未找到路徑。

以下常見原因可導致錯誤 LNK1181:

filename 在鏈接器行上作爲附加依賴項被引用,但該文件不存在。

缺少用於指定包含 filename 的目錄的 /LIBPATH 語句。

若要解決上面的問題,請確保鏈接器行上引用的任何文件在系統中存在。 另外,請確保對於包含依賴於鏈接器的文件的每個目錄都存在 /LIBPATH 語句。

導致 LNK1181 的另一可能原因是具有嵌入空格的長文件名沒有括在引號內。 在這種情況下,鏈接器僅將文件名識別到第一個空格處,然後假定文件的擴展名爲 .obj。 此情況的解決方案是將長文件名(路徑和文件名)括在引號內。


=====================================================================================================================================

15、沒有找到MFC80D.DLL,因此這個程序未能啓動.重新安裝應用程序可能會修復此問題

解決方法:刪除程序目錄下Debug文件夾和Release文件夾,然後重新編譯執行。

===網上其他方法=============

方法一:
沒 有找到MFC80D.DLL的解決方法。問題出現在程序運行清單上,默認是"嵌入清單",清單文件是 "$(IntDir$(TargetFileName).embed.manifest"。調試程序運行時,不知道爲什麼卻定位不到這個文件,我們如果 手動把"程序名.embed.manifest"改爲"程序名.manifest",調試程序即可定位到。

方法二:
在C:Program FilesMicrosoft Visual Studio 8VCredistDebug_NonRedistx86Microsoft.VC80.DebugCRT 下找到了下列文件:
msvcm80d.dll
msvcp80d.dll
msvcr80d.dll
Microsoft.VC80.DebugCRT.manifest
把這幾個文件拷貝到目標機器上,與運行程序同一文件夾或放到system32下,就可以運行那個程序了。

方法三:
修改編譯選項,將/MD或/MDd 改爲 /MT或/MTd,這樣就實現了對VC運行時庫的靜態鏈接,在運行時就不再需要VC的dll了。


=====================================================================================================================================

16、mspdb80.dll無法找到的解決方法

在cmd中鍵入cl執行編譯時會出現mspdb80.dll無法找到的情況,是因爲VCBin下沒有“msobj80.dll,mspdb80.dll,mspdbcore.dll,mspdbsrv.exe”這四個文件,解決的方法:
1>直接從Microsoft Visual Studio 8Common7IDE下複製這四個文件到Microsoft Visual Studio 8VCBin下即可解決
2> 添加系統變量(Path),這樣:我的電腦->屬性->高級->環境變量->系統變量,在path中添加C:Program FilesMicrosoft Visual Studio 8Common7IDE;,注意結尾最後用“;”隔開!
這樣在用cl編譯就不會出現mspdb80.dll文件找不到的錯誤了。


=====================================================================================================================================

17、error LNK2019: 無法解析的外部符號....該符號在函數 ...中被引用

這種情況一般都是函數只找到聲明但沒有實現,或者是少了什麼鏈接庫,你可以試試把那兩個.h和.c文件直接加入工程中再試試。

有一個解決方案,有兩個工程A,B。工程B中定義了一個類,在工程A的demo.cpp中引用該類,但是如果是

#include "XX,h",則會出現“error LNK2019: 無法解析的外部符號”

如果是#include "XX.cpp",則可以順利編譯通過。

想來是因爲引用 .h 文件導致找不到.cpp中的定義,而引用.cpp可以通過.cpp找到.h(.cpp有對.h的include)

但是如果同在工程B下面,則#include "XX,h"也是正確的,它會自動關聯到同名的(反正是對應的).cpp文件。

在不同工程中應該如何引用呢?

看見一種原因分析,如下:

現場情況:

funcname 在文件file.cpp/h中定義實現

void funcname(void) {;}

filecall.c文件內呼叫funcname()函數。

出現上面情況。

症因:因c/c++混合編程, c文件內函數無法呼叫c++文件內函數。

解決,或者將c文件名改爲.cpp,或者將c++文件名改爲.c

上面的解決採用將 file.cpp 更名爲file.c即可。

1.
在 Visual C++ .NET 2003 中,如果使用了 /clr 而未將 CRT 鏈接到可執行文件,將生成此錯誤。任何由編譯器在未使用 /clr:initialAppDomain 時生成的對象代碼都包含對 _check_commonlanguageruntime_version 函數的引用,該函數在 C 運行時庫 (CRT) 中定義。如果應用程序在運行庫的版本 1 上運行,該函數將會生成一個錯誤信息。當前編譯器生成的代碼與運行庫的版本 1 不兼容。因此,如果在 Visual C++ .NET 2003 中編譯時不使用 CRT,則應在代碼中包含 _check_commonlanguageruntime_version 函數的定義。作爲使用 _check_commonlanguageruntime_version 函數的替代方法,您可以與 nochkclr.obj 鏈接。nochkclr.obj 包含該函數的一個空版本,當您在運行庫的版本 1 上運行應用程序時,nochkclr.obj 不生成錯誤信息。若要使用當前編譯器版本生成應用程序以在運行庫的以前版本上運行,應使用 /clr:InitialAppDomain。
若要 生成一個純 MSIL 可執行文件(不與 CRT 鏈接),則必須在項目中定義該函數,而不能使用 nochkclr.obj(.obj 是本機代碼)。有關可驗證代碼的更多信息,請參見產生可驗證的 C++ 託管擴展組件。有關從託管 C++ 項目創建純 MSIL 輸出文件的更多信息,請參見將 C++ 託管擴展項目從混合模式轉換成純 IL。

2.
請看下面的示例:
extern int i;
extern void g();
void f()
{
i++;
g();
}
int main()
{
}
如果在生成中包含的某個文件中沒有定義 i 和 g,鏈接器將生成 LNK2019。可以添加這些定義,方法是將包含這些定義的源代碼文件包括爲編譯的一部分。或者可以將包含這些定義的 .obj 或 .lib 文件傳遞給鏈接器。


3.
對於從早期版本升級到當前版本的 C++ 項目,如果定義了 __UNICODE 並且入口點爲 WinMain,需要將入口點函數的名稱更改爲 _tWinMain 或 _tmain。

4.
符號聲明包含拼寫錯誤,以致於符號聲明與符號定義不同。

5.
使用了一個函數,但其參數的類型或數量與函數定義不匹配。
函數聲明使用和函數定義使用中的調用約定(__cdecl、__stdcall 或 __fastcall)不同。

6.
符號定義在編譯爲 C 程序的文件中,而符號是在 C++ 文件中不帶 extern "C" 修飾符聲明的。在此情況下,請修改聲明,例如不是使用:
extern int i;
extern void g();
而使用:

extern "C" int i;
extern "C" void g();
同樣,如果在將由 C 程序使用的 C++ 文件中定義符號,請在定義中使用 extern "C"。


7.
符號定義爲靜態,但稍後在文件外部被引用。
沒有定義靜態類成員。例如,應單獨定義下面類聲明中的成員變量 si:
#include <stdio.h>
struct X {
static int si;
};

// int X::si = 0; // uncomment this line to resolve

void main()
{
    X *px = new X[2];
    printf("n%d",px[0].si); // LNK2019
}

8.
也可能由於爲 Visual Studio .NET 2003 進行的一致性工作生成此錯誤:模板友元和專用化。在 Visual Studio .NET 2003 中,必須定義聲明新的非模板函數的友元聲明。
要使代碼在 Visual C++ 的 Visual Studio .NET 2003 和 Visual Studio .NET 版本中均有效,請顯式指定友元函數的模板參數列表。
// LNK2019.cpp
// LNK2019 expected
template<class T>
void f(T)
{
}

template<class T>
struct S
{
    friend void f(T);
    // Try the folowing line instead:
    // friend void f<T>(T);
};

int main()
{
    S<int> s;
    f(1); // unresolved external
}


/VERBOSE 鏈接器選項幫助您查看鏈接器引用的文件。DUMPBIN 實用工具的 /EXPORT 和 /SYMBOLS 選項還可以幫助您查看 dll 和對象/庫文件中定義的符號。

-------------------------------------

例如“error LNK2019: 無法解析的外部符號_imp__SetupDiGetDeviceInterfaceDetailW@24
error LNK2001: 無法解析的外部符號“private: static struct _OVERLAPPED CUsbCom::g_WriteOverlapped”

應該是工程設置的問題 沒有連接相應的lib庫或者是所用到的函數沒定義(這個定義是在別的類裏面的)

當出現error LNK2001: 無法解析的外部符號 _print_interface   log.obj      可在log.c裏搜print_interface(無前面_),找到此函數,看有無定義學習VC++時經常會遇到鏈接錯誤LNK2001,該錯誤非常討 厭,因爲對於 編程者來說,最好改的錯誤莫過於編譯錯誤,而一般說來發生連接錯誤時,編譯都已通過。產生連接錯誤的原因非常多,尤其LNK2001錯誤,常常使人不 明其所以然。如果不深入地學習和理解VC++,要想改正連接錯誤LNK2001非 常困難。
初學者在學習VC++的過程中,遇到的LNK2001錯誤的錯誤消息主要爲:
unresolved external symbol “symbol”(不確定的外部“符號”)。 如果連接程序不能在所有的庫和目標文件內找到所引用的函數、變量或 標籤,將產生此錯誤消息。一般來說,發生錯誤的原因有兩個:一是所引用 的函數、變量不存在、拼寫不正確或者使用錯誤;其次可能使用了不同版本的連接庫。
以下是可能產生LNK2001錯誤的原因:
一.由於編碼錯誤導致的LNK2001。
1.不相匹配的程序代碼或模塊定義(.DEF)文件能導致LNK2001。例如, 如果在C++ 源文件內聲明瞭一變量“var1”,卻試圖在另一文件內以變量 “VAR1”訪問該變量,將發生該錯誤。
2.如果使用的內聯函數是在.CPP文件內定義的,而不是在頭文件內定義將導致LNK2001錯誤。
3.調用函數時如果所用的參數類型同函數聲明時的類型不符將會產生 LNK2001。
4.試圖從基類的構造函數或析構函數中調用虛擬函數時將會導致LNK2001。
5.要注意函數和變量的可公用性,只有全局變量、函數是可公用的。
靜態函數和靜態變量具有相同的使用範圍限制。當試圖從文件外部訪問任何沒有在該文件內聲明的靜態變量時將導致編譯錯誤或LNK2001。函數內聲明的變量(局部變量) 只能在該函數的範圍內使用。
C++ 的全局常量只有靜態連接性能。這不同於C,如果試圖在C++的 多個文件內使用全局變量也會產生LNK2001錯誤。一種解決的方法是需要時在頭文件中加入該常量的初始化代碼,並在.CPP文件中包含該頭文件;另一種 方法是使用時給該變量賦以常數。
二.由於編譯和鏈接的設置而造成的LNK2001
1.如果編譯時使用的是/NOD(/NODEFAULTLIB)選項,程序所需要的運行庫和MFC庫在連接時由編譯器寫入目標文件模塊, 但除非在文件中明確包含 這些庫名,否則這些庫不會被鏈接進工程文件。在這種情況下使用/NOD將導 致錯誤LNK2001。
2.如果沒有爲wWinMainCRTStartup設定程序入口,在使用Unicode和MFC時將得到“unresolved external on _WinMain@16”的LNK2001錯誤信息。
3.使用/MD選項編譯時,既然所有的運行庫都被保留在動態鏈接庫之內,源文件中對“func”的引用,在目標文件裏即對“__imp__func” 的引用。
如果試圖使用靜態庫LIBC.LIB或LIBCMT.LIB進行連接,將在__imp__func上發 生LNK2001;如果不使用/MD選項編譯,在使用MSVCxx.LIB連接時也會發生LNK2001。
4.使用/ML選項編譯時,如用LIBCMT.LIB鏈接會在_errno上發生LNK2001。
5.當編譯調試版的應用程序時,如果採用發行版模態庫進行連接也會產生LNK2001;同樣,使用調試版模態庫連接發行版應用程序時也會產生相同的 問題。
6.不同版本的庫和編譯器的混合使用也能產生問題,因爲新版的庫裏可 能包含早先的版本沒有的符號和說明。
7.在不同的模塊使用內聯和非內聯的編譯選項能夠導致LNK2001。如果創建C++庫時打開了函數內聯(/Ob1或/Ob2),但是在描述該函數的相應 頭文件裏卻關閉了函數內聯(沒有inline關鍵字),這時將得到該錯誤信息。 爲避免該問題的發生,應該在相應的頭文件中用inline關鍵字標誌內聯函數。
8.不正確的/SUBSYSTEM或/ENTRY設置也能導致LNK2001。 其實,產生LNK2001的原因還有很多,以上的原因只是一部分而已,對初 學者來說這些就夠理解一陣子了。但是,分析錯誤原因的目的是爲了避免錯 誤的發生。LNK2001錯誤雖然比較困難,但是隻要注意到了上述問題,還是能夠避免和予以解決的。

既然編譯通過了,就說明了沒有語法錯誤,不用在代碼中死摳語法了。從錯誤中提示中找原因吧。

一般問題出在

(1)XXX.lib頭文件,這個要包含(不然編譯也不能通過)

(2)需要XXX.lib或XXX.dll庫。手動添加,項目->屬性->配置屬性->鏈接器->輸入 然後在附件依賴項添加XXX.lib,再生成第一個無法解析的外部符號錯誤消失了。


=====================================================================================================================================

18、Visual Studio 2005不能進行調試,錯誤126: 找不到指定的模塊

Visual Studio 2005一直不能進行調試,查看出錯的原因,是因爲Terminal Services服務不能正確啓動。在【服務】裏嘗試啓動Termial Services服務時,一直提示【錯誤126: 找不到指定的模塊】的錯。上網搜索了一下,發現了這樣的信息:
錯誤126:找不到指定的模塊1. 故障現象嘗試在“服務”管理單元窗口手動啓動服務時,系統提示“錯誤126:找不到指定的模塊”(Error 126: The specified module could not be found.), 2.原因分析該故障通常在由svchost服務宿主進程所啓動的服務上發生。這一類的Windows服務,其實是以dll模塊的形式插入某個 svchost進程。如果該dll文件被破壞,或者註冊表的相關鍵值被篡改,都可能導致問題。這類服務所對應的Dll文件,是由HKLMSYSTEM CurrentControlSetServicesServiceNameParameters註冊表項下的ServiceDll鍵值所定義的 (此處的ServiceName是指服務名),如果該註冊表鍵值出錯,或者對應的Dll文件被破壞,就會導致這個問題。

通過查看註冊表文件,發現【Terminal Services】服務對應與%SystemRoot%System32termsrv.dll文件。查看我的本地文件,不知道何時這個文件名稱被修改了termsrv.dl_。

修改爲termsrv.dll後,再啓動【Terminal Services】服務,正常啓動,調試Visual Studio 2005項目,一切OK!


=======================================================================================================================================

19、MFC 對話框不能顯示中文

在資源視圖中右擊對話框ID,選屬性,修改語言設置

=====================================================================================================================================

20、error C2248: 'CObject::operator =' : cannot access private member declared in class

1>e:program filesmicrosoft visual studio 9.0vcatlmfcincludeafxtempl.h(776) : error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'
1>        e:program filesmicrosoft visual studio 9.0vcatlmfcincludeafx.h(562) : see declaration of 'CObject::operator ='
1>        e:program filesmicrosoft visual studio 9.0vcatlmfcincludeafx.h(532) : see declaration of 'CObject'
1>        This diagnostic occurred in the compiler generated function 'CList<TYPE,ARG_TYPE> &CList<TYPE,ARG_TYPE>::operator =(const CList<TYPE,ARG_TYPE> &)'
1>        with
1>        [
1>            TYPE=CProgram,
1>            ARG_TYPE=CProgram &
1>        ]

上面這段編譯器報警是不是有似曾相識的感覺?想必很多人在用VC2005以及之後的版本的VC編譯器時看到過這個東西,在google查一下error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'你會發現很多人碰到類似的問題。一位叫“中國民工”的blog中說明了引發這一問題的的原因,請參見http://www.cppblog.com/hlong/archive/2007/11/20/37015.html

根據民工兄的解釋,由於我們的類中定義了CArray類型的成員,而CArray<A, A&>類的operator=是private類型(它繼承自CObject::operator=,且被定義爲private類型)。並給出瞭解決之道:如果我們的類/結構體中有CArray(或CList等其他的派生自CObject類)的成員變量,我們最好添加上一個public類型的operator=運算賦重載函數;

問題雖然是解決了,但是似乎還是沒弄明白產生問題的根本原因:既然問題是由於CArray沒有定義Operator=操作從而導致需要調用基類CObject中的私有Operator= 操作而引起的,那麼爲什麼微軟要將CObject的Operator=操作定義成私有呢?或者說爲什麼CObject在實際上並沒有對Operator= 和拷貝構造函數做任何實質性的定義的情況下要去定義這兩個函數,並且還將他們定義爲private。。唯一的解釋就是微軟不希望繼承自CObject的類 使用默認的Operator=操作,或者說微軟不希望使用了CArray或者CList或者CMap的Collections模板類的類使用默認的Operator=操作。答案的確是如此,不僅如此,對於默認的拷貝構造函數結論也是一樣(可能有些人碰到到同樣的編譯器報錯,不過是針對拷貝構造函數的,後面我會解釋引發這兩種類型的報錯的真正原因)。

要想搞清楚這個問 題,就先要了解C++編譯器生成的默認函數——這些我們平時一直在使用卻很少關心的幕後工作者到底是怎樣工作的。當我們創建一個C++變量,爲一個變量賦 值,或者調用一個C++函數,或者對一個C++變量進行取地址&操作時,這些都是一些基本操作,我們總是能得到我們想要的結果(至少看起來是這 樣)因爲這些都是C++的語義,而負責實現這些語義的是C++編譯器。

編譯器又是如何實 現這些語義的呢,比如當你構造一個C++變量時,編譯器會檢查你有沒有爲這個變量的類型創建一個構造函數,如果沒有,編譯器會自己幫你生成一個默認的構造 函數,從而實現了一個C++變量的構造;類似的,在用戶執行其他一些諸如賦值操作,拷貝構造,取地址等基本操作時,編譯器遵循同樣的原則,即在用戶未定義 相應的操作情況下自動生成一個默認的操作;正因爲如此,甚至很多程序員並不知道它們的存在(我記得幾年前我去一家公司面試的時候,就被問及過這樣一個問題:C++類的默認函數有幾個,分別是什麼,,其實這是一個蠻深刻的問題),即使知道它們,也會覺得在不需要我們付出任何關心的情況下,這些操作都是理所應當應該是正確的,但是事實並非總是如此。

Effective C++在條款45也對這幾個函數進行了比較詳細的分析;其中構造函數和析構函數其實就是一個空函數,什麼也不做,所以當我們用VC也好或者其他的C++編 譯器創建一個空類也好,編譯器都會爲我們的類事先定義一個構造和析構函數,就是爲了不讓我們去使用默認的構造和析構函數。所以一般情況下我們很少會忽視這 兩個函數的存在,但是另外3個很重要的函數:拷貝構造和賦值操作符,以及取地址操作符就很容易被忽視掉,因爲我們很少去實現這3個操作,大部分都是使用的 編譯器提供的默認的實現。

對於默認賦值操作符和拷貝構造函數的默認實現,Effective C++上的解釋是:官 方的規則是:缺省拷貝構造函數(賦值運算符)對類的非靜態數據成員進行 "以成員爲單位的" 逐一拷貝構造(賦值)。即,如果m是類C中類型爲T的非靜態數據成員,並且C沒有聲明拷貝構造函數(賦值運算符),m將會通過類型T的拷貝構造函數(賦值 運算符)被拷貝構造(賦值)---- 如果T有拷貝構造函數(賦值運算符)的話。如果沒有,規則遞歸應用到m的數據成員,直至找到一個拷貝構造函數(賦值運算符)或固定類型(例 如,int,double,指針,等)爲止。默認情況下,固定類型的對象拷貝構造(賦值)時是從源對象到目標對象的 "逐位" 拷貝。對於從別的類繼承而來的類來說,這條規則適用於繼承層次結構中的每一層,所以,用戶自定義的構造函數和賦值運算符無論在哪一層被聲明,都會被調用。

另外一個很重要的概念是:當且僅當相應的操作被定義時,編譯器才爲操作變量所屬的類型生成對應的默認操作;也就是說,如果代碼中沒有出現相應的操作,編譯器什麼也不會做。

再回到我們一開始民工兄的例子中,假設我們的類C中定義了一個CArray類型的成員變量,並且C中沒有顯示的定義operator=操作(這就意味着編譯器可能需要爲C自動生成一個默認的operator=操作)根據上面的說法,當且僅當C的實例被賦值時編譯器纔會生 成默認的operator=操作,而編譯器報警告訴我們,編譯器在生成operator=操作時遇到了障礙,這個障礙就是:C的CArray成員具有一個 賦值運算符定義,但是該定義是私有的(實際上是CArray繼承自CObject的operator=定義)。。我們看一下民工兄的例子的源碼:

3struct A
4
{
5
     int a;
6
};
7

8struct B
9
{
10      CArray<A, A&> b;

24};
25

26 typedef CArray<B, B&> C;
27

28void test()
29
{
30
     B b;
31
     C c;
32
     c.Add(b);
33 }

從這段代碼中可以看出,test中對B的實例b並沒有做任何賦值的操作,爲什麼編譯器會去實現B的默認operator=操作呢?

問題就處在CArray::Add()的函數簽名身上,Add函數的源碼如下

template<class TYPE, class ARG_TYPE>
AFX_INLINE INT_PTR CArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)
{ INT_PTR nIndex = m_nSize;
   SetAtGrow(nIndex, newElement);

   return nIndex; }

可見,形參newElement的類型是ARG_TYPE,ARG_TYPE其實就是TYPE的引用,在這裏就是B的引用;答案似乎明瞭了:

因爲Add函數的簽名要求輸入參數的類型爲B&,所以當編譯器編譯語句:c.Add(b); 時會自動將b強制轉換成B的引用,即將這條語句編譯成:B& d = b; c.Add(d); 賦值操作就這樣出現了!

爲了驗證這個想法,可以做另一個測試,調用一個傳值的函數,這樣就不需要做“B& d = b;”的轉換了,那麼就應該不會有問題了。

很不幸,實際上編譯器會報同樣的錯誤,只是現在不是operator=而是拷貝構造函數。

原 因很簡單,因爲對於傳值的方式,實際上就是“通過值來傳遞一個對象”,而這又是由這個對象的類的拷貝構造函數定義的。也就是說當通過傳值的方式調用一個子 程序時,最終是編譯器通過調用拷貝構造函數來實現的。所以問題是一樣的,因爲類型B沒有定義自己的拷貝構造函數,於是編譯器試圖生成一個默認的,但它同樣 遇到了障礙,因爲CArray的拷貝構造也是private的(同樣繼承於CObject)。

至此,我們對於這個問題有了一個比較全面的認識,其實問題的本質在於:不論是默認的operator=還是默認的拷貝構造也好都是有其致命的缺陷的,正如Effective C++條款11中所描述的,當這些默認的實現在遇到需要動態分配內存的類的時候就會出現問題,也就是所謂的深拷貝問題。而Collections模板類就是典型的不能使用默認operator=和默認的拷貝構造的例子。

所以當我們自定義的類中包含Collections模板類的成員時我們就沒法再偷懶使用編譯器自動生成的operator=和的拷貝構造了,而必須自己動手實現,這也是微軟想提醒我們的一個事實。


======================================================================================================================================
21、
error : WINDOWS.H already included. MFC apps must not #include <windows.h>

在windows console下編譯 的時候遇到這個問題的

#include <afx.h>//因爲要用到CString所以要包含這個頭文件
#include <iostream>

using namespace std;

後來把頭文件包含位置換了下 編譯通過
#include <afx.h>//因爲要用到CString所以要包含這個頭文件

#include <iostream>
using namespace std;

error是因爲將#include<stdafx.h>放在其它#include的後面了。
這個文件應該放在最前面。

====================================================================================================
發佈了79 篇原創文章 · 獲贊 91 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章