• _CRT_NONSTDC…与_CRT_SECURE…


    1说明    1

    1.1 _CRT_NONSTDC_NO_WARNINGS    1

    1.2 _CRT_NON_CONFORMING_SWPRINTFS    2

    1.3 _CRT_SECURE_NO_WARNINGS    3

    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.0swprintf的声明

    int swprintf(wchar_t *buffer, const wchar_t *format,...);

    下面是VC++2008swprintf的声明

    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函数。

    解决方法有两个:

    方法一:逐个修改strcpystrcpy_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_COUNT1,因此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,让编译器严格检查安全函数的各个参数。

  • 相关阅读:
    编写高质量代码建议17代码错误调试
    同步和异步的不同场景的概念理解
    kafka版本0.8.2.0-Producer Configs之request.required.acks
    linux的grep命令
    jetty服务器访问系统的域名
    linux工具问题,tail -f 失效
    memcached并发处理
    python爬虫scrapy的Selectors参考文档
    访问nginx提示gateway timeout 504 ,发现总是当调用时间超过30s时提示504错误
    重构再次理解
  • 原文地址:https://www.cnblogs.com/hanford/p/6164305.html
Copyright © 2020-2023  润新知