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

作者:

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
编程 » C++
C++的浮点数转整数有四种方法,直接类型转换、round、floor、ceil。其效果如下表:
编程 » C++, 算法
一个短小、高效的 C++函数,用来判断指定日期是星期几:
编程 » C++, C++11
花括号初始化是 C++11 引入的一种初始化方法。
编程 » C++, 内存检查, Linux
获取程序占用的内存量,是一个诡异的需求。但程序写多了,有时候还真需要,尤其是代码运行出现问题的时候。
armadillo 是一个线性代数 C++库,封装了 blaslapack ,提供更直观的接口。
移动平均 \( \text{ema}(x,n)\) 是指按照如下方法计算指标