假设我有以下代码:
int* intPtr = new int[5];
// ...do stuff...
现在我想将 intPtr 复制到一个新的、相同的数组:
int* newIntPtr = new int[5];
这可以使用简单的 for 循环或 std::copy():
使用for循环
for (int i = 0; i < 5; i++)
*(newIntPtr + i) = *(intPtr + i);
使用 std::copy()
std::copy( intPtr, intPtr + 5, newIntPtr );
使用 std::copy(),我在 Visual Studio 中收到警告:
warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe...
我可以使用
stdext::checked_array_iterator<int*>
让警告消失:
std::copy(intPtr, intPtr + 5, stdext::checked_array_iterator<int*>(newIntPtr, 5));
但这意味着代码无法在 Visual Studio 之外的任何其他平台上编译。
那么,我该如何解决这个问题呢?我应该使用简单的 for 循环并有效避免警告,还是应该使用 std::copy() 并做一些事情来避免警告?显然,我可以禁用警告,但这似乎不是一个合适的解决方案......或者是吗?
在循环中使用
std::copy
有一些好处:
实际上,如果值类型是 TriviallyCopyable,std::copy 的实现会避免多重赋值并使用批量复制函数,例如 std::memmove 来源
正如其他评论所提到的,循环和复制调用同样不安全,因此警告具有误导性。但是,我会避免禁用整个应用程序的安全警告。相反,请使用
#pragma warning (suppress: nnnn)
在本地禁用,请参阅此处。
最明显的优点是使用
std::copy
明确表示
你在做什么。 读者不必分析循环
弄清楚。 第二个优点是代码行数较少。
这并不是绝对的优势;有时会更冗长一些
更好。 但是当你用更少的代码行来制作代码时
更清楚,这绝对是一个优势。
对于其余的:理论上,编译器可以具有以下内置知识: 标准功能,并应用它无法做到的优化 查找用户编写的函数或循环。 在实践中,我不知道 任何编译器都这样做。
回答您关于
std::copy
等潜在好处的问题。阿尔:
好处是,据推测,库实现可能比普通循环(例如 POD 类型的内在函数)更有效。例如,x86 上普通 C 中的
memcpy
可以更容易地优化为小尺寸的 rep movsb
。
至于警告:如果没有意义,应该将其报告为错误,然后禁用/忽略。
在这种情况下,针对库代码对其自身实现的调用发出的警告是无意义的,并且确实需要错误报告。
首先使用 Copy 而不是 for 循环,这样对于大数据来说速度更快。另一方面,您收到的错误有它自己的含义,警告提醒您函数参数值可能是错误的,并且可能会在将来造成损坏。缓冲区溢出的风险。我建议您采纳编译器自己的建议并使用 -D_SCL_SECURE_NO_WARNINGS。