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

코드는 더 이상 사용되지 않음으로 표시된 함수, 클래스 멤버, 변수 또는 typedef를 사용합니다. 기호는 __declspec(deprecated) 한정자 또는 C++14 [[deprecated]] 특성을 사용하여 더 이상 사용되지 않습니다. 실제 C4996 경고 메시지는 선언의 deprecated 한정자 또는 특성(attribute)에 의해 지정됩니다.

중요합니다

이 경고는 항상 기호를 선언하는 헤더 파일 작성자의 의도적인 메시지입니다. 영향을 이해하지 않고 지원 중단된 기호를 사용하지 마세요.

비고

Visual Studio 라이브러리의 많은 함수, 멤버 함수, 함수 템플릿 및 전역 변수는 더 이상 사용되지 않습니다. POSIX 및 Microsoft 관련 함수와 같은 일부 함수는 이제 다른 기본 설정 이름을 가지므로 더 이상 권장되지 않습니다. 일부 C 런타임 라이브러리 함수는 안전하지 않고 더 안전한 대체 버전이 있기 때문에 더 이상 사용되지 않습니다. 다른 항목은 더 이상 쓸모없어 더 이상 권장되지 않습니다. 사용 중단 메시지에는 일반적으로 더 이상 사용되지 않는 함수 또는 전역 변수에 대한 제안된 대체 항목이 포함됩니다.

/sdl (추가 보안 검사 사용) 컴파일러 옵션은 이 경고를 오류로 승격합니다.

경고 끄기

C4996 문제를 해결하려면 일반적으로 코드를 변경하는 것이 좋습니다. 대신 제안된 함수 및 전역 변수를 사용하세요. 이식성을 위해 기존 함수 또는 변수를 사용해야 하는 경우 경고를 해제할 수 있습니다.

특정 코드 줄에 대한 경고 끄기

특정 코드 줄에 대한 경고를 끄려면 warning pragma, #pragma warning(suppress : 4996)를 사용합니다.

파일 내에서 경고 끄기

파일 내에서 이후의 모든 내용에 대한 경고를 해제하려면 경고 pragma #pragma warning(disable : 4996)를 사용합니다.

명령줄 빌드에서 경고를 끄기

명령줄 빌드에서 전역적으로 경고를 끄려면 /wd4996 명령줄 옵션을 사용합니다.

Visual Studio에서 프로젝트에 대한 경고 끄기

Visual Studio IDE에서 전체 프로젝트에 대한 경고를 해제하려면 다음을 수행합니다.

  1. 프로젝트에 대한 속성 페이지 대화 상자를 엽니다. 속성 페이지 대화 상자를 사용하는 방법에 대한 자세한 내용은 속성 페이지를 참조하세요.
  2. 구성 속성>C/C++>고급 속성 페이지를 선택합니다.
  3. 특정 경고 사용 안 함 속성을 편집하여 4996을(를) 추가합니다. 확인을 선택하여 변경 내용을 적용합니다.

전처리기 매크로를 사용하여 경고를 비활성화

전처리기 매크로를 사용하여 라이브러리에서 사용되는 지원 중단 경고의 특정 범주를 비활성화할 수도 있습니다. 이러한 매크로는 아래에 설명되어 있습니다.

Visual Studio에서 전처리기 매크로를 정의하려면 다음을 수행합니다.

  1. 프로젝트에 대한 속성 페이지 대화 상자를 엽니다. 속성 페이지 대화 상자를 사용하는 방법에 대한 자세한 내용은 속성 페이지를 참조하세요.
  2. 확장 구성 속성 > C/C++ > 전처리
  3. 전처리기 정의 속성에서 매크로 이름을 추가합니다. 확인을 선택하여 저장한 다음 프로젝트를 다시 빌드합니다.

특정 소스 파일에서만 매크로를 정의하려면 헤더 파일을 포함하는 모든 줄 앞에 #define EXAMPLE_MACRO_NAME와 같은 줄을 추가합니다.

다음은 C4996 경고 및 오류의 몇 가지 일반적인 소스입니다.

Note

Visual Studio 2017 버전 15.8은 _SCL_SECURE_NO_WARNINGS로 제어되는 Microsoft C++ 표준 라이브러리의 C4996 경고를 제거했습니다. 라이브러리의 현재 버전은 이러한 경고를 내보내지 않습니다. 자세한 내용은 VS 2017 15.8의 STL 기능 및 수정 사항을 참조하세요.

POSIX 함수 이름

이 항목의 POSIX 이름은 더 이상 사용되지 않습니다. 대신 ISO C 및 C++ 준수 이름 new-name을 사용하세요. 자세한 내용은 온라인 도움말을 참조하세요.

Microsoft는 예약된 및 전역 구현 정의 이름에 대한 C99 및 C++03 제약 조건을 준수하도록 CRT에서 일부 POSIX 및 Microsoft 관련 라이브러리 함수의 이름을 변경했습니다. 함수 자체가 아니라 이름만 폐기 예정입니다. 대부분의 경우 함수 이름에 선행 밑줄이 추가되어 규격에 맞는 이름을 만듭니다. 컴파일러는 원래 함수 이름에 대한 사용 중단 경고를 표시하고 권장 이름을 제안합니다.

이 문제를 해결하려면 일반적으로 제안된 함수 이름을 대신 사용하도록 코드를 변경하는 것이 좋습니다. 그러나 업데이트된 이름은 Microsoft 전용입니다. 이식성을 위해 기존 함수 이름을 사용해야 하는 경우 이러한 경고를 해제할 수 있습니다. 함수는 원래 이름으로 라이브러리에서 계속 사용할 수 있습니다.

이러한 함수에 대한 사용 중단 경고를 해제하려면 전처리기 매크로 _CRT_NONSTDC_NO_WARNINGS를 정의하십시오. 옵션을 /D_CRT_NONSTDC_NO_WARNINGS포함하여 명령줄에서 이 매크로를 정의할 수 있습니다.

안전하지 않은 CRT 라이브러리 함수

이 함수 또는 변수는 안전하지 않을 수 있습니다. 대신 safe-version 사용을 고려하세요. deprecated 경고를 사용하지 않도록 설정하려면 _CRT_SECURE_NO_WARNINGS를 사용합니다. 자세한 내용은 온라인 도움말을 참조하세요.

Microsoft는 더 안전한 버전을 사용할 수 있기 때문에 일부 CRT 및 C++ 표준 라이브러리 함수와 전역 변수를 사용 중단 예정입니다. 사용되지 않는 대부분의 함수는 버퍼에 대한 검사되지 않은 읽기 또는 쓰기 액세스를 허용합니다. 그 오용은 보안 문제가 발생할 수 있습니다. 컴파일러는 이러한 함수에 대한 사용 중단 경고를 표시하고 권장 함수를 제안합니다.

이 문제를 해결하려면 함수 또는 변수 safe-version 를 대신 사용하는 것이 좋습니다. 이식성 또는 이전 버전과의 호환성을 이유로 할 수 없는 경우가 있습니다. 버퍼 덮어쓰기 또는 과다 읽기가 코드에서 발생할 수 없는지 신중하게 확인합니다. 그런 다음 경고를 끌 수 있습니다.

CRT에서 이러한 함수의 사용 중단 경고를 해제하려면 _CRT_SECURE_NO_WARNINGS를 정의합니다.

더 이상 사용되지 않는 전역 변수에 대한 경고를 끄려면 _CRT_SECURE_NO_WARNINGS_GLOBALS를 정의합니다.

더 이상 사용되지 않는 이러한 함수 및 전역 변수에 대한 자세한 내용은 CRT의 보안 기능 및 안전한 라이브러리: C++ 표준 라이브러리를 참조하세요.

안전하지 않은 표준 라이브러리 함수

'std:: function_name ::_Unchecked_iterators::_Deprecate' 안전하지 않을 수 있는 매개 변수가 있는 std:: function_name 호출 - 이 호출은 전달된 값이 올바른지 호출자가 확인하는 데 의존합니다. 이 경고를 비활성화하려면 -D_SCL_SECURE_NO_WARNINGS를 사용합니다. Visual C++ 'Checked Iterators'를 사용하는 방법에 대한 자세한 내용은 Checked iterators를 참조하세요.

이 경고는 라이브러리에서 확인할 수 없는 반복기를 사용하여 호출할 때 특정 C++ 표준 라이브러리 함수 템플릿에서 발생합니다. 종종 함수에 컨테이너 경계를 확인하는 데 충분한 정보가 없거나 함수에서 반복기를 잘못 사용하고 있을 수 있습니다. 이 경고는 프로그램에서 보안 문제를 일으킬 수 있는 호출을 식별하는 데 도움이 됩니다. 자세한 내용은 Checked iterators를 참조하세요.

라이브러리는 대상 범위를 추론할 수 있을 때 표준 알고리즘에 전달하는 포인터를 확인된 반복기로 처리합니다. C4996 경고의 이 범주는 검사된 것으로 표시되지 않은 사용자 정의 출력 반복기와 같이 라이브러리가 여전히 확인할 수 없는 경우에 남아 있습니다.

경고를 해결하려면 라이브러리가 이미 확인된 것으로 분류하는 표준 반복기(예: 컨테이너 반복기, std::back_inserter, 또는 std::array 또는 std::span에 대한 반복기)를 사용하세요. 호출이 대상 범위를 초과하지 않는다고 확인되면 _SCL_SECURE_NO_WARNINGS를 정의하여 이 경고를 해제할 수 있습니다.

사용 중단 예정인 C++ 표준 라이브러리 기능

또한 C4996은 코드에서 C++ 표준의 개정판에서 더 이상 사용되지 않게 된 표준 라이브러리 형식, 함수 또는 템플릿을 사용하는 경우에도 발생합니다. 사용 시점에 경고가 나타나고 메시지는 더 이상 사용되지 않는 기호를 식별합니다.

std::iterator는 대표적인 예입니다. C++17 표준에서는 이를 더 이상 권장하지 않으며 최신 표준 준수 모드에는 여전히 포함됩니다(더 이상 권장되지는 않지만 제거되지는 않음). C++17에서 다른 기능(예: std::auto_ptr, std::random_shuffle, std::unary_function 및 std::binary_function)이 제거되었습니다. 기본 /std:c++17 및 이후 모드에서는 해당 항목을 참조하는 코드가 C4996을 내보내는 대신 컴파일되지 않습니다. C4996은 명시적으로 다시 옵트인하는 경우에만 표시됩니다(예: _HAS_AUTO_PTR_ETC=1로 컴파일하거나, 표준 헤더를 포함하기 전에 _HAS_FEATURES_REMOVED_IN_CXX17=1 및 /std:c++14와 같은 매크로를 정의하는 경우).

경고를 해결하려면 사용되지 않는 기호를 최신 기호로 바꾸십시오. 예를 들어 std::iterator에서 반복기 형식을 파생시키는 대신, 반복기 형식에 다섯 개의 반복기 typedef(iterator_category, value_type, difference_type, pointer, reference)를 직접 정의합니다.

// C4996_iterator.cpp
// compile with: cl /c /EHsc /W4 /std:c++20 C4996_iterator.cpp
#include <iterator>

// std::iterator was deprecated in C++17, generates C4996
struct my_iterator : std::iterator<std::input_iterator_tag, int>  // C4996
{
    int* p;
    my_iterator(int* p) : p(p) {}
    int& operator*() { return *p; }
    my_iterator& operator++() { ++p; return *this; }
    my_iterator operator++(int) { auto tmp = *this; ++p; return tmp; }
    bool operator==(const my_iterator& o) const { return p == o.p; }
};

// Fix: declare the iterator typedefs directly.
struct my_iterator_fixed
{
    using iterator_category = std::input_iterator_tag;
    using value_type        = int;
    using difference_type   = std::ptrdiff_t;
    using pointer           = int*;
    using reference         = int&;

    int* p;
    my_iterator_fixed(int* p) : p(p) {}
    int& operator*() { return *p; }
    my_iterator_fixed& operator++() { ++p; return *this; }
    my_iterator_fixed operator++(int) { auto tmp = *this; ++p; return tmp; }
    bool operator==(const my_iterator_fixed& o) const { return p == o.p; }
};

코드를 변경할 수 없는 경우 표준 헤더를 포함하기 전에 적절한 _SILENCE_*_DEPRECATION_WARNING 매크로를 정의하여 이러한 경고를 억제할 수 있습니다. 매크로 이름은 더 이상 사용되지 않는 기능과 관련이 있으며 경고 메시지에 포함됩니다. 예를 들면, _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING의 경우 std::iterator. 지정된 표준에 대해 이러한 모든 경고를 숨기려면 _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS 또는 _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS을 정의하십시오. 이러한 매크로를 프로젝트 전체에서(#define 또는 를 통해) 정의하세요. 표준 헤더가 미리 컴파일된 헤더를 통해 포함되는 경우를 포함해 한 번 처리되고 나면, 사용자 코드에서 나중에 사용하는 /D는 이미 발생한 경고에는 영향을 주지 않습니다.

안전하지 않은 MFC 또는 ATL 코드

보안상의 이유로 더 이상 사용이 권장되지 않는 MFC 또는 ATL 함수를 사용하는 경우 C4996이 발생할 수 있습니다.

이 문제를 해결하려면 업데이트된 함수를 대신 사용하도록 코드를 변경하는 것이 좋습니다.

이러한 경고를 숨기거나 억제하는 방법에 대한 자세한 내용은 다음을 참조하세요 _AFX_SECURE_NO_WARNINGS.

사용되지 않는 CRT 함수 및 변수

이 함수 또는 변수는 최신 라이브러리 또는 운영 체제 기능으로 대체되었습니다. new_item를 대신 사용하는 것이 좋습니다. 자세한 내용은 온라인 도움말을 참조하세요.

일부 라이브러리 함수 및 전역 변수는 더 이상 사용되지 않습니다. 이러한 함수 및 변수는 이후 버전의 라이브러리에서 제거될 수 있습니다. 컴파일러는 이러한 항목에 대해 사용 중단 경고를 표시하고 기본 대안을 제안합니다.

이 문제를 해결하려면 제안된 함수 또는 변수를 사용하도록 코드를 변경하는 것이 좋습니다.

이러한 항목에 대한 사용 중단 경고를 해제하려면 _CRT_OBSOLETE_NO_WARNINGS를 정의합니다. 자세한 내용은 사용되지 않는 함수 또는 변수에 대한 설명서를 참조하세요.

CLR 코드의 마샬링 오류

CLR 마샬링 라이브러리를 사용하는 경우에도 C4996이 발생할 수 있습니다. 이 경우 C4996은 경고가 아니라 오류입니다. 이 오류는 Class가 필요한 두 데이터 형식 간에 변환할 때 를 사용하면 발생합니다. 마샬링 라이브러리가 변환을 지원하지 않는 경우에도 이 오류가 발생할 수 있습니다. 마샬링 라이브러리에 대한 자세한 내용은 C++의 마샬링 개요를 참조하세요.

이 예제에서는 마샬링 라이브러리에서 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;
}

예: 사용자 정의 더 이상 사용되지 않는 함수

특정 함수의 사용을 더 이상 권장하지 않는 경우, 호출자에게 경고하려면 자체 코드에서 [[deprecated]] 특성을 사용하세요. 선언 자체의 특성은 C4996을 발생시키지 않습니다. 사용 중단된 기호를 사용할 때만 C4996이 발생합니다. 이 예제에서는 사용되지 않는 오버로드의 호출 사이트에서 C4996이 생성됩니다.

// C4996.cpp
// compile with: /W3
// C4996 warning expected
#include <stdio.h>

// #pragma warning(disable : 4996)
void func1(void) {
   printf_s("\nIn func1");
}

[[deprecated]]
void func1(int) {
   printf_s("\nIn func1(int)");
}

int main() {
   func1();
   func1(1);    // C4996
}

또한, 다음을 참조하세요.

__declspec(deprecated)
안전한 라이브러리: C++ 표준 라이브러리
CRT의 보안 기능