编译器错误: 带有可能不安全参数的函数调用

17

我有一些不是我的代码,目前它正在产生以下警告:

iehtmlwin.cpp(264) : warning C4996: 'std::basic_string<_Elem,_Traits,_Ax>::copy': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>,
            _Ax=std::allocator<char>
        ]
        c:\program files (x86)\microsoft visual studio 8\vc\include\xstring(1680) : see declaration of 'std::basic_string<_Elem,_Traits,_Ax>::copy'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>,
            _Ax=std::allocator<char>
        ]
这是问题中的代码:
HRESULT STDMETHODCALLTYPE Read(void __RPC_FAR *pv, ULONG cb, ULONG __RPC_FAR *pcbRead)
    {
        if (prepend.size() > 0)
        {
            int n = min(prepend.size(), cb);
            prepend.copy((char *) pv, n);
            prepend = prepend.substr(n);
            if (pcbRead)
                *pcbRead = n;

            return S_OK;
        };

        int rc = Read((char *) pv, cb);
        if (pcbRead)
            *pcbRead = rc;

        return S_OK;
    };

警告涉及到prepend.copy行。我已经尝试谷歌这个警告,但不知道它到底在说什么。请有人帮助我解决这个问题。

Visual Studio 2005 SP1 Windows 7 RC1

编辑:prepend是一个typedefed字符串。

typedef basic_string<char, char_traits<char>, allocator<char> > string;
2个回答

14

这个警告是在告诉你,如果 n 太大的话你就有可能发生缓冲区溢出 -- 尽管你刚刚通过使用 min 的方式避免了这种情况,但可怜的编译器并不知道。我建议你采纳编译器的建议,在这个源文件中使用 -D_SCL_SECURE_NO_WARNINGS ...


5
我最终使用了“#pragma warning( disable : 4996 )”来禁用警告,因为预处理器定义无效。 - Lodle
@alex - 这并不是在声称'n' [可能] 太大。您正在被警告使用一个没有目标大小的目标指针的函数。就其价值而言,定义D_SCL_SECURE_NO_WARNINGS以抑制警告是一个坏主意。 - jww
2
@Lodle - 奇怪的是,在VS2010中,pragma warning(disable: 4996) 对我不起作用;为每个单独的文件(和每个单独的构建)添加 _SCL_SECURE_NO_WARNINGS 到定义中似乎解决了问题。 - Nathan Paul Simons
@Nathan 我的情况正好相反: _SCL... 不起作用,#pragma 能够起作用… - Geier

8
请查看此MSDN页面,了解关于警告的文档。 由于使用std::string::copy方法可能不安全且可能导致缓冲区溢出,因此MS C++编译器决定将其弃用。这种弃用是Microsoft特有的,您可能在其他编译器平台上看不到它。

1
那么禁用它是安全的吗?我正在使用odeint boost来解决微分方程,但出现了这个错误。我正在使用Visual Studio 2013。我使用了#pragma warning( disable : 4996 ),代码可以工作,但不确定是否安全。谢谢。 - CroCo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接