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的后面了。
这个文件应该放在最前面。

====================================================================================================
  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值