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

作者: , 共 2331 字 , 共阅读 0

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 C++编译过程为:
编程 » C++, 编译错误
在 gcc 中,存在继承关系的模版类,子类无法直接访问父类的成员,即使该成员是protectedpublic
编程 » C++, 智能指针
理论上而言,当 C++提供了std::unique_ptr, C++的程序就不应该出现普通指针了。所有普通指针都可以用std::unique_ptr代替,避免手动删除对象。
智能指针在现代 C++里用得越多。以前只知道它大致的原理,比如使用引用计数。但很多实现细节并不清楚,最直接的,它是如何实现多线程安全的?今天找了 gnu c++ library 的实现好好看了一下。
IT » windows terminal
当用 windows terminal 登录 SSH 服务器后:
编程 » C++,
C++的多行宏有标准定义方式,boostfolly库都采用了这种方式:
编程 » C++
现在一般不能用 sprintf 和 strcpy ,推荐使用 snprintf 和 strncpy ,以防止缓冲区溢出:
编程 » C++, gcc
follyLikely.h文件提供了 LIKELY 和 UNLIKELY 宏,提示编译器在分支预测时选择分支。其实现很简单
编程 » C++, Boost, 智能指针
如果理解了侵入式容器,侵入式智能指针也很容易理解。传统的智能指针std::shared_ptr使用了和数据无关的引用计数,这带来两个问题:
armadillo是一个线性代数 C++库,封装了blaslapack,提供更直观的接口。
后一篇:
爬升约 150 到 200 米。长度可长可短,有多条路线可走,一般在 3 到 7 公里。