다음을 통해 공유


컴파일러 경고 (수준 3) C4996

'function'이(가) deprecated로 선언되었습니다. 또한 'std::<function name>': 안전하지 않을 수 있는 매개 변수를 사용하는 함수 호출이며, 이 호출은 호출자가 전달된 값이 올바른지 확인하는 것에 의존합니다.이 경고를 사용하지 않으려면 -D_SCL_SECURE_NO_WARNINGS를 사용합니다.Visual C++ '확인된 반복기' 사용 방법에 대한 설명서를 참조하십시오.

이 경고/오류는 여러 가지 의미를 가질 수 있습니다.

컴파일러가 deprecated라고 표시된 함수를 발견했기 때문에 C4996이 발생할 수 있습니다. 이 함수는 이후 릴리스에서 제공되지 않을 수 있습니다. 다음 예제와 같이 warning pragma를 사용하여 이 경고를 해제할 수 있습니다.

일부 CRT 및 표준 C++ 라이브러리 함수는 보안이 강화된 새 함수로 대체되어 더 이상 사용되지 않습니다. 대신 사용할 함수에 대한 자세한 내용은 오류 메시지의 사용되지 않는 함수에 대한 설명서를 참조하십시오. CRT 사용 중단을 해제하려면 _CRT_SECURE_NO_WARNINGS를 정의합니다. 더 이상 사용되지 않는 함수에 대한 자세한 내용은 CRT의 보안 기능안전한 라이브러리: C++ 표준 라이브러리를 참조하십시오.

<hash_map> 및**<hash_set>** 헤더 파일의 멤버를 std 네임스페이스에 사용하면 C4996이 발생합니다. 자세한 내용은 stdext 네임스페이스를 참조하십시오.

보안상의 이유로 더 이상 사용되지 않는 MFC나 ATL 함수를 사용하는 경우에도 C4996이 발생할 수 있습니다. 이러한 경고가 발생하지 않게 하려면 _AFX_SECURE_NO_WARNINGS_ATL_SECURE_NO_WARNINGS를 참조하십시오.

또한 C4996은 마샬링 라이브러리를 사용할 때 발생할 수 있습니다. 이 경우 C4996은 경고가 아니라 오류입니다. 이 오류는 marshal_context 클래스가 필요한 두 데이터 형식 간의 변환을 위해 marshal_as를 사용할 때 발생합니다. 마샬링 라이브러리가 변환을 지원하지 않을 때 이 오류가 발생하기도 합니다. 마샬링 라이브러리에 대한 자세한 내용은 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로 설정) 컴파일할 때 확인된 반복기를 사용하지 않는 경우에 발생할 수 있습니다. 자세한 내용은 Checked Iterators를 참조하십시오.

다음 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;
}