#pragma warning( disable: XXXX ) 未按预期运行(范围问题)

#pragma warning( disable: XXXX ) does not behave as expected (scope issue)

考虑这个程序:

#include <string>
#include <boost/random.hpp>

int main(int argc, char *argv[])
{
    return 0;
}

使用 VS2015 编译,我从 boost\random\detail\polynomial.hpp 文件中收到警告 4996。

d:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility(2810): warning C4996: 'std::_Fill_n': 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'
  d:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility(2797): note: voir la déclaration de 'std::_Fill_n'
  d:\dev\vobs_ext_2015\libcpp\boost.60.0\boost\random\detail\polynomial.hpp(114): note: voir la référence à l'instanciation de la fonction modèle '_OutIt std::fill_n<boost::random::detail::polynomial_ops::digit_t*,size_t,boost::random::detail::polynomial_ops::digit_t>(_OutIt,_Diff,const _Ty &)' en cours de compilation
          with
          [
              _OutIt=boost::random::detail::polynomial_ops::digit_t *,
              _Diff=size_t,
              _Ty=boost::random::detail::polynomial_ops::digit_t
          ]

所以我尝试禁用警告:

#include <string>

#pragma warning(push)
#pragma warning( disable: 4996 ) // disable warning coming from boost/random.hpp
#include <boost/random.hpp>
#pragma warning(pop)

int main(int argc, char *argv[])
{
    return 0;
}

仍然报告警告....然后我尝试了:

#pragma warning(push)
#pragma warning( disable: 4996 ) // disable warning coming from boost/random.hpp
#include <string>
#include <boost/random.hpp>
#pragma warning(pop)

int main(int argc, char *argv[])
{
    return 0;
}

现在它消失了...为什么我需要在 pragma push/pop 指令中包含 #include <string>

警告来自内部 header 文件 <xutility>。该文件首先被 <string> 包含,然后被 <boost/random.hpp> 包含(并且它可能第二次被忽略)。如果你想抑制这个警告,你需要在第一次包含 header 时抑制它,但你发现很难知道这是什么时候。

无论如何这是一个有点奇怪的警告 - 它只是说这个调用可能不安全但编译器不能告诉,而不是它实际上不安全。你可以简单地按照警告说的那样做,并使用项目设置中的 _SCL_SECURE_NO_WARNINGS 定义将其关闭(或者在你包含任何 header 之前,或者在你的 pch 中,如果你使用它)

jpo38 编辑:

这将删除警告:

#pragma warning(push)
#pragma warning( disable: 4996 ) // disable warning coming from boost/random.hpp
#include <boost/random.hpp>
#pragma warning(pop)

#include <string>

所以问题确实来自 <xutility> 被包含在 <boost/random.hpp><string> 中。由于 <xutility> 它可以防止多次包含(它有一个 #pragma once),必须禁用警告 4996,而首先包含 <xutility>