編譯器警告 (層級 3) C4996
'function' : 已經宣告為取代 也 'std::<函式名稱>':含參數的函式呼叫可能不安全 - 此呼叫須由呼叫端檢查通過值是否正確。若要停用這項警告,請使用 - D_SCL_SECURE_NO_WARNINGS。請參閱有關如何使用 Visual C++ 'Checked Iterators' 的文件
這個警告/錯誤多種可能含意。
由於編譯器遇到標記為已被取代 的函式,所以可能會發生 C4996。 未來的版本可能不再支援此函式。 您可以使用 warning pragma 關閉此警告 (下面的範例)。
有些 CRT 函式和 Standard C++ 程式庫函式已經由更安全的新函式取代。 如需有關要改用哪一個函式的詳細資訊,請參閱錯誤訊息中已被取代函式的文件。 若要關閉 CRT 取代警告訊息,請定義 _CRT_SECURE_NO_WARNINGS。 如需已遭取代函式的詳細資訊,請參閱 CRT 中的安全性功能和安全程式庫:C++ 標準程式庫。
如果您在 std 命名空間中使用 <hash_map> 和 <hash_set> 標頭檔的成員,您將會看見 C4996。 如需詳細資訊,請參閱 stdext 命名空間。
如果您使用因安全考量而被取代的 MFC 或 ATL 函式,也可能會發生 C4996。 若要抑制這些警告,請參閱 _AFX_SECURE_NO_WARNINGS 和 _ATL_SECURE_NO_WARNINGS。
當您使用封送處理程式庫時,也可能會發生 C4996。 在此情況下,C4996 是錯誤而非警告。 當您使用 marshal_as 在兩個需要 marshal_context 類別 的資料類型之間進行轉換時,將會發生這個錯誤。 當封送處理不支援某項轉換時,也會發生這個錯誤。 如需封送處理程式庫的詳細資訊,請參閱 C++ 中封送處理的概觀。
在第一個例子中,宣告函式的程式行及使用函式的程式行會產生 C4996。
範例
下列範例會產生 C4996。
// C4996.cpp
// compile with: /W3
// C4996 warning expected
#include <stdio.h>
// #pragma warning(disable : 4996)
void func1(void) {
printf_s("\nIn func1");
}
__declspec(deprecated) void func1(int) {
printf_s("\nIn func2");
}
int main() {
func1();
func1(1);
}
用已定義的 _ITERATOR_DEBUG_LEVEL 進行編譯時 (偵錯模式組建設定預設為 1),如果您未使用已檢查的迭代器,也可能會發生 C4996。如需詳細資訊,請參閱已檢查的迭代器。
下列 STL 程式碼範例會產生 C4996。
// C4996_b.cpp
// compile with: /EHsc /W3 /c
#define _ITERATOR_DEBUG_LEVEL 1
#include <algorithm>
#include <iterator>
using namespace std;
using namespace stdext;
int main() {
int a[] = { 1, 2, 3 };
int b[] = { 10, 11, 12 };
copy(a, a + 3, b + 1); // C4996
// try the following line instead
// copy(a, a + 3, b);
copy(a, a + 3, checked_array_iterator<int *>(b, 3)); // OK
}
下列 STL 程式碼範例會產生 C4996 警告。 註解已內嵌。
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
template <typename C> void print(const string& s, const C& c) {
cout << s;
for (const auto& e : c) {
cout << e << " ";
}
cout << endl;
}
int main()
{
vector<int> v(16);
iota(v.begin(), v.end(), 0);
print("v: ", v);
// OK: vector::iterator is checked in debug mode
// (i.e. an overrun will trigger a debug assertion)
vector<int> v2(16);
transform(v.begin(), v.end(), v2.begin(), [](int n) { return n * 2; });
print("v2: ", v2);
// OK: back_insert_iterator is marked as checked in debug mode
// (i.e. an overrun is impossible)
vector<int> v3;
transform(v.begin(), v.end(), back_inserter(v3), [](int n) { return n * 3; });
print("v3: ", v3);
// OK: array::iterator is checked in debug mode
// (i.e. an overrun will trigger a debug assertion)
array<int, 16> a4;
transform(v.begin(), v.end(), a4.begin(), [](int n) { return n * 4; });
print("a4: ", a4);
// OK: Raw arrays are checked in debug mode
// (i.e. an overrun will trigger a debug assertion)
// NOTE: This applies only when raw arrays are given to STL algorithms!
int a5[16];
transform(v.begin(), v.end(), a5, [](int n) { return n * 5; });
print("a5: ", a5);
// WARNING C4996: Pointers cannot be checked in debug mode
// (i.e. an overrun will trigger undefined behavior)
int a6[16];
int * p6 = a6;
transform(v.begin(), v.end(), p6, [](int n) { return n * 6; });
print("a6: ", a6);
// OK: stdext::checked_array_iterator is checked in debug mode
// (i.e. an overrun will trigger a debug assertion)
int a7[16];
int * p7 = a7;
transform(v.begin(), v.end(), stdext::make_checked_array_iterator(p7, 16), [](int n) { return n * 7; });
print("a7: ", a7);
// WARNING SILENCED: stdext::unchecked_array_iterator is marked as checked in debug mode
// (i.e. it performs no checking, so an overrun will trigger undefined behavior)
int a8[16];
int * p8 = a8;
transform(v.begin(), v.end(), stdext::make_unchecked_array_iterator(p8), [](int n) { return n * 8; });
print("a8: ", a8);
}
下列範例會產生 C4996 錯誤,因為封送處理程式庫需要內容,才能從 System::String 轉換為 const char *。
// C4996_Marshal.cpp
// compile with: /clr
// C4996 expected
#include <stdlib.h>
#include <string.h>
#include <msclr\marshal.h>
using namespace System;
using namespace msclr::interop;
int main() {
String^ message = gcnew String("Test String to Marshal");
const char* result;
result = marshal_as<const char*>( message );
return 0;
}