忽视或关闭编译警告,都是非常草率的行为。“注意你的编译警告信息,并及时改正编译所提示的错误。如果你忽略了明显错误的话,你就难以改正微妙的错误。”—《代码大全》。
一方面,编译警告确实隐藏了非常致命的代码缺陷,另一方面,认为不用处理“无害”警告是缺乏团队责任心的表现,会给整个项目引入大量的警告信息,把真正有问题的警告淹没在大量警告信息中,对整个团队开发带来恶劣影响。
在项目中对编译警告采取零容忍的态度,如果编译警告确实不易清除,在明确知道原因以后其产生的影响时,可报告项目负责人,在项目编译选项中忽略警告。
VS警告等级含义:
关 : 关闭所有警告(/W0) : 关闭所有警告消息的显示。
1 级(/W1) : 显示严重的警告消息。
2 级(/W2) : 显示等级 1 警告以及某些不太严重的警告,如关于隐藏类成员的警告。这是命令行中的默认警告等级。
3 级(/W3) : 显示等级 2 警告以及某些不太严重的警告,如有关总是计算为真或假的表达式的警告。VS默认等级为/W3。
4 级(/W4) : 显示所有等级 3 警告以及信息性警告
如果对warning要求比较高,可以将warning提升为error,要求必须处理才能运行程序。
大多数编译警告处理起来几乎不会增加额外开发负担,下表列出几种常见编译警告和解决措施:
Warning |
Solution |
for(int ix = 0; ix < vec.Size(); ix++) |
Recommend: for (vector ix != vec.size(); ix++) for (auto it = vec.begin(); it != vec.end(); it++) for (auto ix : vec) |
warning: missing initializer for member 'struct::member' |
Complete initialization in the struct. |
warning: suggest parentheses around comparison in operand of [operator] |
Use () to increase readability regardless of operation priority. |
warning : The name 'frame' (QFrame) is already in use, defaulting to 'frame1'. |
|
warning C4005: 'XXX': macro redefinition |
Delete or rename one of them. |
C4018 – Signed/unsigned mismatch C4244: '=': Conversion from 'type1' to 'type2', possible loss of data C4245 – Conversion from 'type1' to 'type2', signed/unsigned mismatch |
Make sure you understand how the data is going to get converted then use x_cast to explicitly cast the data to match types. Type conversions and type safety | Microsoft Docs |
C4065 – Switch statement contains 'default' but no 'case' labels |
This may happen with code created by a code generation such as yacc or bison. Correct the input files to avoid this warning. Eg: switch (x) { default: break; } |
C4067 – Unexpected tokens following preprocessor directive - expected a newline |
The main reason one would get this error is because C++ used to allow arbitrary text after a preprocessor directives, such as: #ifdef _DEBUG ... #endif _DEBUG The text after the #endif is now illegal. To fix, change code to look like this: #ifdef _DEBUG ... #endif // _DEBUG #include #if defined(X); // C4067 To resolve this warning, delete the stray characters, or move them into a comment block. |
C4081 – Expected 'token1'; found 'token2' C4097 – Expected pragma parameter to be 'token1' or 'token2' |
See message Eg: #pragma optimize) "l", on ) // C4081: expected '('; found ')' |
warning C4091: 'typedef ' : ignored on left of 'SPREADSHEET' when no variable is declared |
Delete typedef. It's the C way of declaring structs, C++ does it automatically for you. Eg: // Spreadsheet structure typedef struct SPREADSHEET { int ID; // ID of the spreadsheet UINT nLines; // Number of lines void CopyFrom(const SPREADSHEET* src) { ID = src->ID; nLines = src->nLines; } }; |
C4100 – Unreferenced formal parameter |
If it is interface inheritance, function callback, third party library, etc., it does not need: You can use macros such as'Q_UNUSED', ' UNREFERENCED_PARAMETER ', etc. Eg: int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); } |
C4101 – Unreferenced local variable C4102 – Unreferenced label C4189 – Local variable is initialized by not referenced |
It’s best to just remove the variable. If it’s there because it’s used by some other code that’s currently commented out, remove the variable and code that’s commented out. If the variable is there to view its result in the debugger, then you can disable this particular instance of the warning by referencing the variable immediately after the declaration: short objectId = 0; objectId; // for debugging |
warning C4129: 'D': unrecognized character escape sequence |
Make sure the "\\" in the path is correct |
warning C4146: Unary minus operator applied to unsigned type, result still unsigned |
Should never happen in our own code. If it happens in 3rd party code, disable it. Eg: 2147483648 is out of int range on your platform. Either use a type with more precision to represent the constant int val = -2147483648L; // or int val = -2147483648LL; or : int val = -2147483647 - 1; |
warning C4150: deletion of pointer to incomplete type 'XXX'; no destructor called |
class IncClass; void NoDestruct( IncClass* pIncClass ) { delete pIncClass; } // C4150, define class to resolve The compiler warning is because the compiler was unable to find the type IncClass's destructor. Put the implementation of IncClass to header file and include the file in this CPP. |
warning C4172: returning address of local variable or temporary |
Eg: CCommunicationWnd::GetCurrentUSBGUID-> replace with member variable CImageStack::GetCellAnalysisOuputInfo-> replace with other code CImageStack::GetBoolOperationCellAnalysisOuputInfo->add static |
warning C4192: automatically excluding 'XXX' while importing type library 'library' |
Use no_auto_exclude and include(…) #import attributes to turn of automatic exclusion of duplicates and specify names explicitly. The problem is because those to importlib directives caused IStream and ISequentialStream defined inside the typelib - MSDN explains it and says I have to either use include or no_auto_exclude with #import. Eg: #import exclude("ISequentialStream","_FILETIME")named_guids |
C4273 –'Function' : inconsistent DLL linkage |
Use consistent dllimport qualifier __declspec. Eg: char __declspec(dllimport) c; char c; // C4273, delete this line or the line above to resolve |
C4302 – 'type cast': truncation from 'LPSTR' to 'WORD C4310 – Cast truncates constant value |
Your using the wrong data type with the constant value. Either pick constant in range or change the data type. |
warning C4305: '=': truncation from 'double' to 'float' |
3.14->3.14f |
warning C4312: 'type cast': conversion from 'UINT' to 'HWND' of greater size |
Doing a double type cast like this: (HMENU)(UINT_PTR)id |
warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) |
1->1ULL |
C4506 – No definition for inline function 'function' C4710 – Function not inlined |
The given function was declared and marked for inlining but was not defined. The compiler did not inline the function. Make sure that external functions to be inlined are declared with the extern keyword. See message. |
C4663 – To explicitly specialize a template class, use the new syntax. |
Add template<> in front of the class declaration for an explicitly specialized class template. template template<> class X class X |
C4700 – Local variable used without having been initialized C4701 – Local variable 'name' may be used without having been initialized |
Be careful with this warning. It could actually point to a software defect. The only time this is valid to have is when a variable is passed by reference to a function. The compiler doesn’t know that it’s okay for the input variable to not be initialized (C++ allows this.) To remove this warning, initialize the variable before using it. |
C4702 – Unreachable code |
Remove the dead code, or if the code isn’t dead, fix the control paths. |
C4706 – Assignment within conditional expression |
Assignments within conditional expressions should not be made. Fix the code. Eg: int main() { int a = 0, b = 0; if ( a = b ) // C4706 { } } |
warning C4715: Not all control paths return a value |
If the compiler is correct, this usually indicates a software defect and the code needs to be fixed. The compiler is sometimes wrong. For instance, it may not know that a function you are calling never returns (such as ThrowError().) Simply change the code to throw anything immediately after, or simply return. |
warning C4805: '&=': unsafe mix of type 'bool' and type 'BOOL' in operation |
Eg: BOOL B = TRUE; bool b = true; if (B == b) { // C4805, } You can change to same type or cast. |
warning C4819: The file contains a character that cannot be represented in the current code page (936). Save the file in Unicode format to prevent data loss |
Save the file as ANSI. |
warning C4996: 'XXX': was declared deprecated |
Must not use deprecated functions unless explicitly identified in the project development plan as to why. The warning content will explain the replacement method, you can refer to the replacement, otherwise it may have a large impact.For example, in Windows 8 getVersion () can only return 6.2. After the replacement, it is best to verify whether the new method is used correctly, such as input parameters, resource release, etc. |
warning C4996: 'std::array |
array.asign()->array.fill() assign (Obsolete. Use fill.) Replaces all elements. Eg: std::array drawPlate.assign(false); |
warning C4996: 'XXX': This function or variable may be unsafe. Consider using XXX_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. |
Replace it with XXX_s(XXX_s is a non-standard library function, and the arguments should also be matched). |
warning C4996: |
'qSort': Use std::sort 'QTableWidgetItem::backgroundColor': Use QTableWidgetItem::background() instead 'QTableWidgetItem::setBackgroundColor': Use QTableWidgetItem::setBackground() instead 'QTableWidgetItem::setTextColor': Use QTableWidgetItem::setForeground() instead 'QListWidget::setItemSelected': Use QListWidgetItem::setSelected() instead 'QFontMetrics::width': Use QFontMetrics::horizontalAdvance 'QPalette::Background': Use QPalette::Window instead 'cv::estimateRigidTransform': was declared deprecated 'QStyleOptionViewItemV4': was declared deprecated |
warning MSB8027: Two or more files with the name of xxxx.cpp will produce outputs to the same location. This can lead to an incorrect build result. |
ExcludedFromBuild Condition missing, open.vcxproj for editing, refer to other .cpp content items to complete. Eg:
|
error: LNK2001: unresolved external symbol "public: virtual void * __thiscall Parent::qt_metacast(char const *)" (?qt_metacast@Parent@@UAEPAXPBD@Z) |
If you're using Visual Studio, delete the line Q_OBJECT from the header file, save the file, put Q_OBJECT back into the header file, save the file again. This should generate the moc_* file and should build and link correctly. |
CyAPI.lib(CyAPI.obj) : error LNK2019: unresolved external symbol sprintf referenced in function "public: void __cdecl CCyUSBDevice::UsbdStatusString(unsigned long,char *)" (?UsbdStatusString@CCyUSBDevice@@QEAAXKPEAD@Z) |
Add additional dependency library: legacy_stdio_defines.lib (setupapi. lib is mandatory). |
LINK : warning LNK4098: defaultlib "LIBCMTD" conflicts with use of other libs; use /NODEFAULTLIB:library |
Linker->Input->Ignore Specific Default Libraries input libcmt |