C++ 常见和不常见的编译警告和错误

作者: , 共 2337 字

1. 禁止函数指针和对象指针(包括 void )的转换

出现的一个场景是将函数指针用 void

warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object [-Wpedantic]

这个警告只有在gcc编译器并且开启pedantic编译选项才会出来。vs不会有提示。为避免此警告,可以在代码前添加__extension__。为保证可移植性,最佳方式是:

#ifdef __GNUC__
__extension__
#endif
the_statement_that_includes_the_cast;

这个是理论上是符合 C++标准。解释如下:

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

2. _WIN32_WINNT 未被定义

vs编译项目有时候会有下面这一条警告:

_WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
- add -D_WIN32_WINNT=0x0501 to the compiler command line; or
- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).

这个警告的原因是程序中用到了 windows 的 API ,程序在编译时需确定 API 的版本。如果有确定的版本,就用确定的版本。有时候实际上没有用到特别的 API ,此时可以简单在头文件或stdafx.h中指定_WIN32_WINNT=0x0501,也可以在编译选项中添加-D_WIN32_WINNT=0x0501

3. C4996(_CRT_SECURE_NO_WARNINGS)错误

很多人推荐大学的非专业的 C++学习者直接用 vc6 而不是 vs ,其中一个很大的原因是 vs 的配置项太多,非专业学习者会比较迷惑。这个便是其中的一个。_CRT_SECURE_NO_WARNINGS是一个VS新手面临的最常见同时又难以理解的错误。这个错误主要原因是,VS以安全为由,禁止了某些不安全的C++函数。常见的错误信息如下:

 error C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

理论上而言,在代码文件的最前端(或者stdafx.h文件中,若有)直接添加宏可以抑制该警告提示:

#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif

或者添加下面这一行:

#pragma  warning(disable:4996)

但这种方法并不一定总是能行,原因不明。所以可以采取下面两种方法:

一、右击工程 - 属性 - 配置属性 - C/C++ - 命令行,命令行增加/D _CRT_SECURE_NO_WARNINGS

二、在 Project properties->Configuration Properties->C/C++->Preprocessor->Preprocessor 里添加_CRT_SECURE_NO_WARNING

要注意, VS 在debugrelease两个编译模式下分别使用两套配置,这两套配置下都需要修改。注意第二种方法里,两种编译模式的预定义量(Preprocessor)的默认值不一样,不能简单复制粘贴给弄成一样的。否则编译时会出现非预期的结果。

Q. E. D.

类似文章:
编程 » C++, 编译错误
在 gcc 中,存在继承关系的模版类,子类无法直接访问父类的成员,即使该成员是protectedpublic
最近老遇到一个奇怪的问题。在 VS 2013 编译时,爆出很多警告:
编程 » Matlab, swap, 函数包
Matlab 程序效率低下,其中一个原因就是它的参数无法引用,每次都是传值。这不但导致效率问题,要实现某些功能,也需要一些特殊的手段。比如最简单的,如果交换两个变量的值,也就是在 C/C++里的函数 void swap(int& a, int& b),在 C/C++里实现很容易,但在 Matlab 里,你会吗?
编程 » C++, GCC, 编译链接
LD 在链接生成目标文件时,会从左到有扫描输入的依赖库,当依赖库之间也有依赖关系时,必须将「依赖别人的库」放在「被别人依赖的库」的前面。否则会链接失败!失败的症状有:
相似度: 0.054
编程 » Excel, VBA
Excel VBA 出错时给出的错误信息极少,需要充分利用各种工具来进行调试。
相似度: 0.053
编程 » C++, 算法
一个短小、高效的 C++函数,用来判断指定日期是星期几:
armadillo是一个线性代数 C++库,封装了blaslapack,提供更直观的接口。
移动平均\( \text{ema}(x,n)\) 是指按照如下方法计算指标