_CRT_NONSTDC…与_CRT_SECURE…
目录
1.1 _CRT_NONSTDC_NO_WARNINGS 1
1.2 _CRT_NON_CONFORMING_SWPRINTFS 2
1.4 _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 4
1.5 _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 5
第1章说明
1.1 _CRT_NONSTDC_NO_WARNINGS
使用VC++2008编译如下代码:
|
#include <windows.h> #include <tchar.h> #include <math.h> int WINAPI _tWinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { hypot(3,4); return 0; } |
将收到如下警告信息:
|
warning C4996: 'hypot': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _hypot. See online help for details. |
错误原因:hypot函数是符合POSIX标准的函数,在VC++2008下这个标准已经过时,被ISO C++取代。在ISO C++标准下,该函数的名称为_hypot。
解决方法有两个:
方法一:把hypot更改为_hypot。如:#define hypot _hypot
方法二:定义宏_CRT_NONSTDC_NO_WARNINGS或_CRT_NONSTDC_NO_DEPRECATE。更改后的代码如下:
|
#define _CRT_NONSTDC_NO_WARNINGS #include <windows.h> #include <tchar.h> #include <math.h> int WINAPI _tWinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { hypot(3,4); return 0; } |
说明:
1、#define _CRT_NONSTDC_NO_WARNINGS必须在#include语句之前;
2、#define _CRT_NONSTDC_NO_DEPRECATE 与 #define _CRT_NONSTDC_NO_WARNINGS 完全等效。
1.2 _CRT_NON_CONFORMING_SWPRINTFS
使用VC++2008编译如下代码:
|
#include <windows.h> #include <tchar.h> #include <stdio.h> int WINAPI _tWinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { wchar_t wzStr[32]; swprintf(wzStr,L"%d",10); return 0; } |
将收到如下警告信息:
|
warning C4047: 'function' : 'size_t' differs in levels of indirection from 'unsigned short [3]' warning C4024: 'swprintf' : different types for formal and actual parameter 2 warning C4047: 'function' : 'const wchar_t *' differs in levels of indirection from 'int' warning C4024: 'swprintf' : different types for formal and actual parameter 3 |
错误原因:swprintf的声明被更改了!
下面是VC++6.0里swprintf的声明
int swprintf(wchar_t *buffer, const wchar_t *format,...);
下面是VC++2008里swprintf的声明
int swprintf(wchar_t *buffer,size_t count,const wchar_t *format,...);
可见后者多了一个参数size_t count。
解决方法有两个:
方法一:逐个修改swprintf函数。工作量大不说,遇到_stprintf函数时还得分两种情况更改代码。而且最重要的是更改之后VC++6.0就无法编译了;
方法二:定义宏 _CRT_NON_CONFORMING_SWPRINTFS,继续沿用老版本的swprintf。更改后的代码如下:
|
#define _CRT_NON_CONFORMING_SWPRINTFS #include <windows.h> #include <tchar.h> #include <stdio.h> int WINAPI _tWinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { wchar_t wzStr[32]; swprintf(wzStr,L"%d",10); return 0; } |
1.3 _CRT_SECURE_NO_WARNINGS
使用VC++2008编译如下代码:
|
#include <windows.h> #include <tchar.h> #include <stdio.h> int WINAPI _tWinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { char szBuf[10]; strcpy(szBuf,"test"); return 0; } |
将收到如下警告信息:
|
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. |
错误原因:VC++2008认为strcpy函数不安全,建议您将其替换为strcpy_s函数。
解决方法有两个:
方法一:逐个修改strcpy为strcpy_s,工作量比较大;
方法二:定义宏 _CRT_SECURE_NO_WARNINGS或_CRT_SECURE_NO_DEPRECATE,继续使用不安全的strcpy函数。更改后的代码如下:
|
#define _CRT_SECURE_NO_WARNINGS #include <windows.h> #include <tchar.h> #include <stdio.h> int WINAPI _tWinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { char szBuf[10]; strcpy(szBuf,"test"); return 0; } |
1.4 _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
上一节只是把strcpy的警告信息去除了,现在想把strcpy都替换为安全的strcpy_s函数,有什么快捷的方法?答案就是使用宏_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES和_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT。
参考下面的代码:
|
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1 #include <windows.h> #include <tchar.h> #include <stdio.h> #include <string.h> int WINAPI _tWinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { char szBuf[10]; strcpy(szBuf,"test"); strncpy(szBuf,"test",10); return 0; } |
说明:
1、因为定义了宏_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 为1,因此strcpy会被替换为strcpy_s(szBuf,sizeof(szBuf),"test");
2、因为定义了宏_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT为1,因此strncpy(szBuf,"test",10);会被替换为strncpy_s(szBuf,sizeof(szBuf),"test",10);
3、这种替换方法只适用于静态数组,不适用于动态数组;
4、这两个宏只能用于C++代码,对于C代码是没有任何作用的。
1.5 _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES
参考下面的代码:
|
#include <windows.h> #include <tchar.h> #include <stdio.h> #include <string.h> int WINAPI _tWinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { char szBuf[10]; strcpy_s(szBuf,"test"); return 0; } |
strcpy_s需要三个参数,上面的代码里只有两个(程序员不熟悉strcpy_s,把它当成strcpy用)。为什么编译时没有提示错误?
因为宏_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES在默认情况下被定义为1,在这种情况下编译器会自动给strcpy_s添加缺失的参数,即修改strcpy_s(szBuf,"test");为strcpy_s(szBuf,sizeof(szBuf),"test");
说明:
1、这种替换方法只适用于静态数组,不适用于动态数组;
2、这个宏只能用于C++代码,对于C代码是没有任何作用的;
3、既然决定使用安全函数,最好还是把_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES定义为0,让编译器严格检查安全函数的各个参数。
_CRT_NONSTDC…与_CRT_SECURE…的更多相关文章
随机推荐
- Codeforces Round #370 (Div. 2) A
Description There are n integers b1, b2, ..., bn written in a row. For all i from 1 to n, values ai ...
- C语言培训第一天
下面是一些命令,先来谈谈今天的若干收获吧! 计算机中的一切文件都是以二进制补码的形式存在,问题也就来了. 第一个问题 如果我们给一个无符号的数赋值一个负数,他会读取到什么,又会输出什么?(似乎问题和上 ...
- C++析构函数定义为虚函数(转载)
转载:http://blog.csdn.net/alane1986/article/details/6902233 析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数.如果析构函数不是虚函 ...
- 我的android学习经历28
一道题目关于Layout_weight: 当前屏幕的大小为430,有左右两个控件,未分配权重之前都是300,左控件的权重是3,右控件的权重是2,请计算左右两个控件的宽度大小是多少? 解: 当前屏幕剩余 ...
- Cheatsheet: 2013 06.01 ~ 06.22
.NET Git for Visual Studio and .NET developers How to download multiple files concurrently using Web ...
- Django忘记管理员账号和密码的解决办法
看着Django的教程学习搭建网站,结果忘记第一次创建的账号和密码了.结果搭建成功以后,一直无法登陆到管理页面,进行不下去了. 如图所示: 在网上找了很多的方法都不行,最后使用新建一个superuse ...
- web后门top
看到了一个博客 觉得关键点很有用 1)出现频率最高的DDoS后门文件名 abc.php, xl.php, Xml.php, dedetag.class.php, counti.php, plase. ...
- Servlet&jsp基础:第二部分
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- \n ^ \t的使用
\n是换行符: 使用时需要放在字符串里面,成为字符串的一部分(不要嫌乱,这是我之前犯的错误). 示例: >>>print("I am Guido \n what's yon ...
- 在SQL Server中 获取日期、日期格式转换
--常用日期转换参数: PRINT CONVERT(varchar, getdate(), 120 ) 2016-07-20 16:09:01 PRINT replace(replace(replac ...