Compiler Warning (level 3) C4996

Kode Anda menggunakan fungsi, anggota kelas, variabel, atau typedef yang ditandai tidak digunakan lagi. Simbol tidak digunakan lagi dengan menggunakan __declspec(deprecated) pengubah, atau atribut C++14 [[deprecated]] . Pesan peringatan C4996 aktual ditentukan oleh pengubah deprecated atau atribut deklarasi.

Penting

Peringatan ini selalu merupakan pesan yang disarankan dari penulis file header yang mendeklarasikan simbol. Jangan gunakan simbol yang tidak digunakan lagi tanpa memahami konsekuensinya.

Keterangan

Banyak fungsi, fungsi anggota, templat fungsi, dan variabel global di pustaka Visual Studio tidak digunakan lagi. Beberapa, seperti POSIX dan fungsi khusus Microsoft, tidak digunakan lagi karena sekarang memiliki nama pilihan yang berbeda. Beberapa fungsi pustaka runtime C tidak digunakan lagi karena tidak aman dan memiliki varian yang lebih aman. Yang lain tidak digunakan lagi karena sudah usang. Pesan penghentian biasanya menyertakan penggantian yang disarankan untuk fungsi yang tidak digunakan lagi atau variabel global.

/sdl Opsi kompilator (Aktifkan Pemeriksaan Keamanan Tambahan) meningkatkan peringatan ini menjadi kesalahan.

Menonaktifkan peringatan

Untuk memperbaiki masalah C4996, kami biasanya menyarankan Anda mengubah kode Anda. Gunakan fungsi yang disarankan dan variabel global sebagai gantinya. Jika Anda perlu menggunakan fungsi atau variabel yang ada karena alasan portabilitas, Anda dapat menonaktifkan peringatan.

Menonaktifkan peringatan untuk baris kode tertentu

Untuk menonaktifkan peringatan untuk baris kode tertentu, gunakan warning pragma, #pragma warning(suppress : 4996).

Menonaktifkan peringatan dalam file

Untuk menonaktifkan peringatan dalam file untuk semua yang berikut, gunakan pragma peringatan, #pragma warning(disable : 4996).

Menonaktifkan peringatan dalam build baris perintah

Untuk menonaktifkan peringatan secara global dalam build baris perintah, gunakan /wd4996 opsi baris perintah.

Menonaktifkan peringatan untuk proyek di Visual Studio

Untuk menonaktifkan peringatan untuk seluruh proyek di IDE Visual Studio:

  1. Buka dialog Halaman Properti untuk proyek Anda. Untuk informasi tentang cara menggunakan dialog Halaman Properti, lihat Halaman Properti.

  2. Pilih halaman properti Properti>Konfigurasi C/C++>Tingkat Lanjut.

  3. Edit properti Nonaktifkan Peringatan Tertentu untuk menambahkan 4996. Pilih OK untuk menerapkan perubahan Anda.

Menonaktifkan peringatan menggunakan makro praprosesor

Anda juga dapat menggunakan makro praprosesor untuk menonaktifkan kelas tertentu dari peringatan penghentian yang digunakan dalam pustaka. Makro ini dijelaskan di bawah ini.

Untuk menentukan makro praprosesor di Visual Studio:

  1. Buka dialog Halaman Properti untuk proyek Anda. Untuk informasi tentang cara menggunakan dialog Halaman Properti, lihat Halaman Properti.

  2. Perluas Properti > Konfigurasi C/C++ > Preprocessor.

  3. Di properti Definisi Praprosesor, tambahkan nama makro. Pilih OK untuk menyimpan, lalu bangun kembali proyek Anda.

Untuk menentukan makro hanya dalam file sumber tertentu, tambahkan baris seperti #define EXAMPLE_MACRO_NAME sebelum baris apa pun yang menyertakan file header.

Berikut adalah beberapa sumber umum peringatan dan kesalahan C4996:

Nama fungsi POSIX

The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: new-name. See online help for details.

Microsoft mengganti nama beberapa fungsi pustaka khusus POSIX dan Microsoft di CRT agar sesuai dengan batasan C99 dan C++03 pada nama yang dicadangkan dan ditentukan implementasi global. Hanya nama yang tidak digunakan lagi, bukan fungsi itu sendiri. Dalam kebanyakan kasus, garis bawah terkemuka ditambahkan ke nama fungsi untuk membuat nama yang sesuai. Kompilator mengeluarkan peringatan penghentian untuk nama fungsi asli, dan menyarankan nama yang disukai.

Untuk memperbaiki masalah ini, kami biasanya menyarankan Anda mengubah kode untuk menggunakan nama fungsi yang disarankan sebagai gantinya. Namun, nama yang diperbarui khusus Microsoft. Jika Anda perlu menggunakan nama fungsi yang ada untuk alasan portabilitas, Anda dapat menonaktifkan peringatan ini. Fungsi ini masih tersedia di pustaka dengan nama aslinya.

Untuk menonaktifkan peringatan penghentian untuk fungsi-fungsi ini, tentukan makro _CRT_NONSTDC_NO_WARNINGSpraprosesor . Anda dapat menentukan makro ini di baris perintah dengan menyertakan opsi /D_CRT_NONSTDC_NO_WARNINGS.

Fungsi Pustaka CRT tidak aman

This function or variable may be unsafe. Consider using safe-version instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Microsoft menghentikan beberapa fungsi dan global Pustaka Standar CRT dan C++ karena versi yang lebih aman tersedia. Sebagian besar fungsi yang tidak digunakan lagi memungkinkan akses baca atau tulis yang tidak dicentang ke buffer. Penyalahgunaan mereka dapat menyebabkan masalah keamanan yang serius. Kompilator mengeluarkan peringatan penghentian untuk fungsi-fungsi ini, dan menyarankan fungsi yang disukai.

Untuk memperbaiki masalah ini, kami sarankan Anda menggunakan fungsi atau variabel safe-version sebagai gantinya. Terkadang Anda tidak dapat, karena alasan kompatibilitas portabilitas atau mundur. Verifikasi dengan hati-hati bahwa tidak mungkin terjadi penimpaan atau overread buffer dalam kode Anda. Kemudian, Anda dapat mematikan peringatan.

Untuk menonaktifkan peringatan penghentian untuk fungsi-fungsi ini di CRT, tentukan _CRT_SECURE_NO_WARNINGS.

Untuk menonaktifkan peringatan tentang variabel global yang tidak digunakan lagi, tentukan _CRT_SECURE_NO_WARNINGS_GLOBALS.

Untuk informasi selengkapnya tentang fungsi dan global yang tidak digunakan lagi ini, lihat Fitur Keamanan di Pustaka CRT dan Brankas: Pustaka Standar C++.

Fungsi Pustaka Standar tidak aman

'std:: function_name ::_Unchecked_iterators::_Deprecate' Call to std:: function_name with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'

Di Visual Studio 2015, peringatan ini muncul di build debug karena templat fungsi Pustaka Standar C++ tertentu tidak memeriksa parameter untuk kebenaran. Seringkali itu karena tidak cukup informasi yang tersedia untuk fungsi untuk memeriksa batas kontainer. Atau, karena iterator mungkin salah digunakan dengan fungsi . Peringatan ini membantu Anda mengidentifikasi fungsi-fungsi ini, karena mungkin merupakan sumber lubang keamanan serius dalam program Anda. Untuk informasi selengkapnya, lihat Iterator yang diperiksa.

Misalnya, peringatan ini muncul dalam mode Debug jika Anda meneruskan penunjuk elemen ke std::copy, alih-alih array biasa. Untuk memperbaiki masalah ini, gunakan array yang dideklarasikan dengan tepat, sehingga pustaka dapat memeriksa tingkat array dan melakukan pemeriksaan batas.

// C4996_copyarray.cpp
// compile with: cl /c /W4 /D_DEBUG C4996_copyarray.cpp
#include <algorithm>

void example(char const * const src) {
    char dest[1234];
    char * pdest3 = dest + 3;
    std::copy(src, src + 42, pdest3); // C4996
    std::copy(src, src + 42, dest);   // OK, copy can tell that dest is 1234 elements
}

Beberapa algoritma pustaka standar diperbarui untuk memiliki versi "rentang ganda" di C++14. Jika Anda menggunakan versi rentang ganda, rentang kedua menyediakan pemeriksaan batas yang diperlukan:

// C4996_containers.cpp
// compile with: cl /c /W4 /D_DEBUG C4996_containers.cpp
#include <algorithm>

bool example(
    char const * const left,
    const size_t leftSize,
    char const * const right,
    const size_t rightSize)
{
    bool result = false;
    result = std::equal(left, left + leftSize, right); // C4996
    // To fix, try this form instead:
    // result = std::equal(left, left + leftSize, right, right + rightSize); // OK
    return result;
}

Contoh ini menunjukkan beberapa cara lagi pustaka standar dapat digunakan untuk memeriksa penggunaan iterator, dan ketika penggunaan yang tidak dicentang mungkin berbahaya:

// C4996_standard.cpp
// compile with: cl /EHsc /W4 /MDd C4996_standard.cpp
#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 triggers 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 triggers 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 triggers a debug assertion)
    // NOTE: This applies only when raw arrays are
    // given to C++ Standard Library 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 triggers 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 triggers 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, but it performs no checking,
    // so an overrun triggers 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);
}

Jika Anda telah memverifikasi bahwa kode Anda tidak dapat memiliki kesalahan buffer-overrun, Anda dapat menonaktifkan peringatan ini. Untuk menonaktifkan peringatan untuk fungsi-fungsi ini, tentukan _SCL_SECURE_NO_WARNINGS.

Iterator yang diperiksa diaktifkan

C4996 juga dapat terjadi jika Anda tidak menggunakan iterator yang diperiksa ketika _ITERATOR_DEBUG_LEVEL didefinisikan sebagai 1 atau 2. Ini diatur ke 2 secara default untuk build mode debug, dan ke 0 untuk build ritel. Untuk informasi selengkapnya, lihat Iterator yang diperiksa.

// C4996_checked.cpp
// compile with: /EHsc /W4 /MDd C4996_checked.cpp
#define _ITERATOR_DEBUG_LEVEL 2

#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, checked_array_iterator<int *>(b, 3));   // OK
}

Kode MFC atau ATL tidak aman

C4996 dapat terjadi jika Anda menggunakan fungsi MFC atau ATL yang tidak digunakan lagi karena alasan keamanan.

Untuk memperbaiki masalah ini, kami sangat menyarankan Anda mengubah kode untuk menggunakan fungsi yang diperbarui sebagai gantinya.

Untuk informasi tentang cara menekan peringatan ini, lihat _AFX_SECURE_NO_WARNINGS.

Fungsi dan variabel CRT usang

This function or variable has been superseded by newer library or operating system functionality. Consider using new_item instead. See online help for details.

Beberapa fungsi pustaka dan variabel global tidak digunakan lagi sebagai usang. Fungsi dan variabel ini dapat dihapus dalam versi pustaka di masa mendatang. Kompilator mengeluarkan peringatan penghentian untuk item ini, dan menyarankan alternatif yang disukai.

Untuk memperbaiki masalah ini, kami sarankan Anda mengubah kode untuk menggunakan fungsi atau variabel yang disarankan.

Untuk menonaktifkan peringatan penghentian untuk item ini, tentukan _CRT_OBSOLETE_NO_WARNINGS. Untuk informasi selengkapnya, lihat dokumentasi untuk fungsi atau variabel yang tidak digunakan lagi.

Kesalahan marshaling dalam kode CLR

C4996 juga dapat terjadi ketika Anda menggunakan pustaka marshaling CLR. Dalam hal ini, C4996 adalah kesalahan, bukan peringatan. Kesalahan terjadi saat Anda menggunakan marshal_as untuk mengonversi antara dua jenis data yang memerlukan marshal_context Kelas. Anda juga dapat menerima kesalahan ini ketika pustaka marshaling tidak mendukung konversi. Untuk informasi selengkapnya tentang pustaka marshaling, lihat Gambaran Umum marshaling di C++.

Contoh ini menghasilkan C4996 karena pustaka marshaling memerlukan konteks untuk dikonversi dari menjadi System::Stringconst 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;
}

Contoh: Fungsi yang tidak digunakan lagi yang ditentukan pengguna

Anda dapat menggunakan deprecated atribut dalam kode Anda sendiri untuk memperingatkan penelepon ketika Anda tidak lagi merekomendasikan penggunaan fungsi tertentu. Dalam contoh ini, C4996 dihasilkan di dua tempat: Satu untuk baris fungsi yang tidak digunakan lagi dideklarasikan, dan satu untuk baris tempat fungsi digunakan.

// 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 func2");
}

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