コンパイラの警告 (レベル 3) C4996
'function' が古い形式として宣言されました ( "std::<function name>"): パラメーターが指定されている関数呼び出しが安全でない可能性があります。この呼び出しは、呼び出し元を使用して、渡された値が正しいかどうかを確認します。この警告を無効にするには、-D_SCL_SECURE_NO_WARNINGS を使用します。Visual C++ の "チェックを行う反復子" の使用方法に関するドキュメントを参照してください。
この警告とエラーには、さまざまな意味が考えられます。
deprecated でマークされている関数が見つかると、C4996 が発生する可能性があります。 この関数は、将来のリリースではサポートされなくなる可能性があります。 この警告は、warning プラグマを使用するとオフにできます。以下の例を参照してください。
セキュリティが強化された新しい関数が優先されるので、一部の CRT 関数および標準 C++ ライブラリ関数は使用されなくなっています。 代わりに使用する関数の詳細については、エラー メッセージの推奨されていない関数に関するドキュメントを参照してください。 CRT 廃止警告をオフにするには、_CRT_SECURE_NO_WARNINGS を定義します。 サポートされなくなった関数の詳細については、「CRT のセキュリティ機能」および「安全なライブラリ: C++ 標準ライブラリ」を参照してください。
C4996 は、<hash_map> ヘッダー ファイルと <hash_set> ヘッダー ファイルのメンバーを std 名前空間で使用している場合に発生します。 詳細については、「The stdext Namespace」を参照してください。
C4996 は、セキュリティ上の理由から使用されなくなった MFC 関数または ATL 関数を使用している場合にも発生することがあります。 この警告が表示されないようにするには、「_AFX_SECURE_NO_WARNINGS」および「_ATL_SECURE_NO_WARNINGS」を参照してください。
C4996 は、マーシャリング ライブラリを使用しているときも発生します。 この場合、C4996 はエラーであり、警告ではありません。 このエラーは、marshal_as を使用して marshal_context クラスを必要とする 2 つのデータ型間で変換を行うときに発生します。 マーシャリング ライブラリが変換をサポートしていないときにもこのエラーが発生します。 マーシャリング ライブラリの詳細については、「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);
}
C4996 は、_ITERATOR_DEBUG_LEVEL を定義してコンパイルするときに、チェックを行う反復子を使用しない場合にも発生することがあります (デバッグ モードのビルドでは既定で 1 に設定)。詳細については、「チェックを行う反復子」を参照してください。
次の 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);
}
次の例では、マーシャリング ライブラリが System::String を const char * に変換するときにコンテキストを必要とするため、C4996 が生成されます。
// 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;
}