Derleyici Uyarısı (düzey 3) C4996
Kodunuz kullanım dışı olarak işaretlenmiş bir işlev, sınıf üyesi, değişken veya tür tanımı kullanıyor. Simgeler, değiştirici __declspec(deprecated)
veya C++14 [[deprecated]]
özniteliği kullanılarak kullanım dışı bırakılmıştır. Gerçek C4996 uyarı iletisi, bildirimin deprecated
değiştiricisi veya özniteliği tarafından belirtilir.
Önemli
Bu uyarı her zaman üst bilgi dosyasının yazarından gelen ve simgeyi bildiren kasıtlı bir iletidir. Sonuçlarını anlamadan kullanım dışı bırakılmış simgeyi kullanmayın.
Açıklamalar
Visual Studio kitaplıklarındaki birçok işlev, üye işlevi, işlev şablonu ve genel değişken kullanım dışıdır. POSIX ve Microsoft'a özgü işlevler gibi bazı işlevler artık farklı bir tercih edilen ada sahip oldukları için kullanım dışı bırakılmıştır. Bazı C çalışma zamanı kitaplığı işlevleri, güvenli olmadığından ve daha güvenli bir varyanta sahip olduklarından kullanım dışıdır. Diğerleri kullanımdan kaldırıldıkları için kullanım dışıdır. Kullanımdan kaldırma iletileri genellikle kullanım dışı bırakılan işlev veya genel değişken için önerilen bir değiştirme içerir.
/sdl
(Ek Güvenlik Denetimlerini Etkinleştir) derleyici seçeneği bu uyarıyı bir hataya yükseltir.
Uyarıyı kapatma
C4996 sorununu düzeltmek için genellikle kodunuzu değiştirmenizi öneririz. Bunun yerine önerilen işlevleri ve genel değişkenleri kullanın. Taşınabilirlik nedeniyle mevcut işlevleri veya değişkenleri kullanmanız gerekiyorsa uyarıyı kapatabilirsiniz.
Belirli bir kod satırı için uyarıyı kapatma
Belirli bir kod warning
satırı için uyarıyı kapatmak için pragma, #pragma warning(suppress : 4996)
kullanın.
Dosya içindeki uyarıyı kapatma
Bir dosyadaki uyarıyı izleyen her şey için kapatmak için uyarı pragması olan #pragma warning(disable : 4996)
öğesini kullanın.
Komut satırı derlemelerinde uyarıyı kapatma
Uyarıyı komut satırı derlemelerinde genel olarak kapatmak için komut satırı seçeneğini kullanın /wd4996
.
Visual Studio'da bir proje için uyarıyı kapatma
Visual Studio IDE'de projenin tamamı için uyarıyı kapatmak için:
Projeniz için Özellik Sayfaları iletişim kutusunu açın. Özellik Sayfaları iletişim kutusunun nasıl kullanılacağı hakkında bilgi için bkz . Özellik Sayfaları.
Yapılandırma Özellikleri>C/C++>Gelişmiş özellik sayfasını seçin.
Eklemek
4996
için Belirli Uyarıları Devre Dışı Bırak özelliğini düzenleyin. Değişikliklerinizi uygulamak için Tamam'ı seçin.
Ön işlemci makrolarını kullanarak uyarıyı devre dışı bırakma
Ayrıca, kitaplıklarda kullanılan belirli kullanımdan kaldırma uyarı sınıflarını kapatmak için önişlemci makrolarını da kullanabilirsiniz. Bu makrolar aşağıda açıklanmıştır.
Visual Studio'da bir önişlemci makro tanımlamak için:
Projeniz için Özellik Sayfaları iletişim kutusunu açın. Özellik Sayfaları iletişim kutusunun nasıl kullanılacağı hakkında bilgi için bkz . Özellik Sayfaları.
Yapılandırma Özellikleri C/C++ > Önişlemcisi'ni> genişletin.
Önişlemci Tanımları özelliğine makro adını ekleyin. Kaydetmek için Tamam'ı seçin ve projenizi yeniden oluşturun.
Makroları yalnızca belirli kaynak dosyalarda tanımlamak için, üst bilgi dosyası içeren herhangi bir satırın önüne gibi #define EXAMPLE_MACRO_NAME
bir satır ekleyin.
C4996 uyarılarının ve hatalarının yaygın kaynaklarından bazıları şunlardır:
POSIX işlev adları
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, ayrılmış ve genel uygulama tanımlı adlarda C99 ve C++03 kısıtlamalarıyla uyumlu olması için CRT'deki bazı POSIX ve Microsoft'a özgü kitaplık işlevlerini yeniden adlandırdı. İşlevlerin kendileri değil, yalnızca adlar kullanım dışıdır. Çoğu durumda, uyumlu bir ad oluşturmak için işlev adına önde gelen bir alt çizgi eklenmiştir. Derleyici, özgün işlev adı için bir kullanımdan kaldırma uyarısı oluşturur ve tercih edilen adı önerir.
Bu sorunu çözmek için genellikle kodunuzu önerilen işlev adlarını kullanacak şekilde değiştirmenizi öneririz. Ancak, güncelleştirilmiş adlar Microsoft'a özgüdür. Taşınabilirlik nedeniyle mevcut işlev adlarını kullanmanız gerekiyorsa, bu uyarıları kapatabilirsiniz. İşlevler, özgün adlarının altında kitaplıkta hala kullanılabilir.
Bu işlevler için kullanımdan kaldırma uyarılarını kapatmak için önişlemci makrosunu _CRT_NONSTDC_NO_WARNINGS
tanımlayın. seçeneğini /D_CRT_NONSTDC_NO_WARNINGS
ekleyerek bu makroyu komut satırında tanımlayabilirsiniz.
Güvenli olmayan CRT Kitaplığı işlevleri
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, daha güvenli sürümler kullanılabildiğinden bazı CRT ve C++ Standart Kitaplığı işlevlerini ve genel işlevlerini kullanım dışı bırakılmıştır. Kullanım dışı bırakılan işlevlerin çoğu, arabelleklere işaretsiz okuma veya yazma erişimi sağlar. Kötüye kullanımları ciddi güvenlik sorunlarına yol açabilir. Derleyici, bu işlevler için bir kullanımdan kaldırma uyarısı oluşturur ve tercih edilen işlevi önerir.
Bu sorunu çözmek için bunun yerine işlevini veya değişkenini safe-version
kullanmanızı öneririz. Bazen taşınabilirlik veya geriye dönük uyumluluk nedeniyle bunu yapamazsınız. Bir arabelleğin üzerine yazma veya aşırı okumanın kodunuzda gerçekleşmesinin mümkün olmadığını dikkatle doğrulayın. Ardından uyarıyı kapatabilirsiniz.
CRT'de bu işlevler için kullanımdan kaldırma uyarılarını kapatmak için tanımlayın _CRT_SECURE_NO_WARNINGS
.
Kullanım dışı bırakılmış genel değişkenlerle ilgili uyarıları kapatmak için tanımlayın _CRT_SECURE_NO_WARNINGS_GLOBALS
.
Bu kullanım dışı bırakılan işlevler ve genel ayarlar hakkında daha fazla bilgi için bkz . CRT ve Güvenli Kitaplıklardaki Güvenlik Özellikleri: C++ Standart Kitaplığı.
Güvenli Olmayan Standart Kitaplık işlevleri
'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'
Visual Studio 2015'te bu uyarı hata ayıklama derlemelerinde görünür çünkü bazı C++ Standart Kitaplığı işlev şablonları parametrelerin doğruluğunu denetlemez. Bunun nedeni genellikle kapsayıcı sınırlarını denetlemek için işlev için yeterli bilgi olmamasıdır. Öte yandan yineleyiciler işlevde yanlış kullanıldığından da olabilir. Bu uyarı, programınızda ciddi güvenlik açıklarının kaynağı olabileceğinden bu işlevleri belirlemenize yardımcı olur. Daha fazla bilgi için bkz . İşaretli yineleyiciler.
Örneğin, bu uyarı düz dizi yerine öğesine bir öğe işaretçisi std::copy
geçirirseniz Hata Ayıklama modunda görünür. Bu sorunu düzeltmek için, kitaplığın dizi kapsamlarını denetleyebilmesi ve sınır denetimi yapması için uygun şekilde bildirilen bir dizi kullanın.
// 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
}
C++14'te "çift aralıklı" sürümlere sahip olacak şekilde çeşitli standart kitaplık algoritmaları güncelleştirildi. Çift aralıklı sürümleri kullanırsanız, ikinci aralık gerekli sınır denetimini sağlar:
// 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;
}
Bu örnekte, standart kitaplığın yineleyici kullanımını denetlemek için kullanılabilmesinin ve işaretsiz kullanımın tehlikeli olabileceği birkaç farklı yol gösterilmektedir:
// 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);
}
Kodunuzun arabellek taşması hatasına sahip olmadığını doğruladıysanız, bu uyarıyı kapatabilirsiniz. Bu işlevlere yönelik uyarıları kapatmak için tanımlayın _SCL_SECURE_NO_WARNINGS
.
İşaretli yineleyiciler etkinleştirildi
1 veya 2 olarak tanımlandığında _ITERATOR_DEBUG_LEVEL
denetlenmiş bir yineleyici kullanmazsanız da C4996 oluşabilir. Hata ayıklama modu derlemeleri için varsayılan olarak 2, perakende derlemeleri için 0 olarak ayarlanır. Daha fazla bilgi için bkz . İşaretli yineleyiciler.
// 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
}
Güvenli olmayan MFC veya ATL kodu
Güvenlik nedeniyle kullanım dışı bırakılan MFC veya ATL işlevlerini kullanırsanız C4996 oluşabilir.
Bu sorunu çözmek için, bunun yerine kodunuzu güncelleştirilmiş işlevleri kullanacak şekilde değiştirmenizi kesinlikle öneririz.
Bu uyarıları gizleme hakkında bilgi için bkz _AFX_SECURE_NO_WARNINGS
. .
Eski CRT işlevleri ve değişkenleri
This function or variable has been superseded by newer library or operating system functionality. Consider using
new_item
instead. See online help for details.
Bazı kitaplık işlevleri ve genel değişkenler kullanımdan kaldırıldı. Bu işlevler ve değişkenler kitaplığın gelecek bir sürümünde kaldırılabilir. Derleyici, bu öğeler için bir kullanımdan kaldırma uyarısı düzenler ve tercih edilen alternatifi önerir.
Bu sorunu çözmek için kodunuzu önerilen işlevi veya değişkeni kullanacak şekilde değiştirmenizi öneririz.
Bu öğeler için kullanımdan kaldırma uyarılarını kapatmak için tanımlayın _CRT_OBSOLETE_NO_WARNINGS
. Daha fazla bilgi için kullanım dışı bırakılan işlev veya değişkenin belgelerine bakın.
CLR kodunda hataları hazırlama
C4996, CLR hazırlama kitaplığını kullandığınızda da oluşabilir. Bu durumda, C4996 bir hatadır, uyarı değildir. Hata, sınıf marshal_context
gerektiren iki veri türü arasında dönüştürme yapmak için kullandığınızda marshal_as
oluşur. Ayrıca, sıralama kitaplığı dönüştürmeyi desteklemediğinde de bu hatayı alabilirsiniz. Hazırlama kitaplığı hakkında daha fazla bilgi için bkz . C++'da sıralamaya genel bakış.
Bu örnek C4996 oluşturur çünkü hazırlama kitaplığı için bir'den System::String
öğesine dönüştürmek için bir const char *
bağlam gerekir.
// 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;
}
Örnek: Kullanıcı tanımlı kullanım dışı işlevi
Artık belirli işlevlerin deprecated
kullanılmasını önermediğinizde çağıranları uyarmak için kendi kodunuzda özniteliğini kullanabilirsiniz. Bu örnekte, C4996 iki yerde oluşturulur: Biri kullanım dışı bırakılan işlevin bildirildiği satır için, diğeri de işlevin kullanıldığı satır için.
// 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
}