Upozornění kompilátoru (úroveň 3) C4996
Váš kód používá funkci, člen třídy, proměnnou nebo definici typedef, která je označena jako zastaralá. Symboly jsou zastaralé pomocí __declspec(deprecated) modifikátoru nebo atributu C++14. [[deprecated]] Skutečná zpráva upozornění C4996 je určena deprecated modifikátorem nebo atributem deklarace.
Důležité
Toto upozornění je vždy úmyslná zpráva od autora souboru hlaviček, který deklaruje symbol. Nepoužívejte zastaralý symbol bez pochopení důsledků.
Poznámky
Mnoho funkcí, členských funkcí, funkcí šablon a globálních proměnných v Visual Studio jsou zastaralé. Některé funkce, například POSIX a specifické pro Microsoft, jsou zastaralé, protože teď mají jiný upřednostňovaný název. Některé funkce knihovny modulu runtime jazyka C jsou zastaralé, protože jsou nezabezpečené a mají bezpečnější variantu. Jiné jsou zastaralé, protože jsou zastaralé. Zprávy o vyněcování obvykle obsahují navrhované nahrazení zastaralé funkce nebo globální proměnné.
Vypnutí upozornění
Pokud chcete problém c4996 vyřešit, obvykle doporučujeme změnit kód. Místo toho použijte navrhované funkce a globální proměnné. Pokud z důvodů přenositelnosti potřebujete použít existující funkce nebo proměnné, můžete upozornění vypnout.
Vypnutí upozornění pro konkrétní řádek kódu
Pokud chcete upozornění pro konkrétní řádek kódu vypnout, použijte warning direktivu pragma #pragma warning(suppress : 4996) .
Vypnutí upozornění v souboru
Pokud chcete upozornění v souboru vypnout pro všechno, co následuje, použijte direktivu pragma upozornění #pragma warning(disable : 4996) .
Vypnutí upozornění v sestaveních příkazového řádku
Pokud chcete upozornění v sestaveních příkazového řádku globálně vypnout, použijte /wd4996 možnost příkazového řádku.
Vypněte upozornění pro projekt v Visual Studio
Vypnutí upozornění pro celý projekt v integrovaném vývojovém Visual Studio ideu:
Otevřete dialogové okno Stránky vlastností pro váš projekt. Informace o tom, jak používat dialogové okno Stránky vlastností, najdete v tématu Stránky vlastností.
Vyberte stránku vlastnostíUpřesnit vlastnosti konfigurace C/C++.
Úpravou vlastnosti Disable Specific Warnings (Zakázat konkrétní upozornění) přidejte . Pokud chcete změny použít, zvolte OK.
Zakázání upozornění pomocí preprocesorových maker
Pomocí preprocesorových maker můžete také vypnout určité konkrétní třídy upozornění na vyrušování používaných v knihovnách. Tato makra jsou popsána níže.
Definice makra preprocesoru v Visual Studio:
Otevřete dialogové okno Stránky vlastností pro váš projekt. Informace o tom, jak používat dialogové okno Stránky vlastností, najdete v tématu Stránky vlastností.
Rozbalte vlastnosti konfigurace preprocesoru > C/C++.
Do vlastnosti Definice preprocesoru přidejte název makra. Kliknutím na OK projekt uložte a pak ho znovu sestavte.
Chcete-li definovat makro pouze v konkrétních zdrojových souborech, přidejte řádek, například před libovolný #define EXAMPLE_MACRO_NAME řádek, který obsahuje soubor záhlaví.
Tady jsou některé běžné zdroje upozornění a chyb C4996:
Názvy funkcí 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.
Společnost Microsoft přejmenuje některé funkce knihovny posix a specifické pro Microsoft v CRT tak, aby odpovídaly omezením C99 a C++03 pro vyhrazené a globální názvy definované implementací. Pouze názvy jsou zastaralé, nikoli samotné funkce. Ve většině případů bylo k názvu funkce přidáno úvodní podtržítko, aby se vytvořil odpovídající název. Kompilátor pro původní název funkce vydá upozornění na vyněcování a navrhne upřednostňovaný název.
Pokud chcete tento problém vyřešit, obvykle doporučujeme změnit kód tak, aby místo toho místo toho byl používat navrhované názvy funkcí. Aktualizované názvy jsou však specifické pro Společnost Microsoft. Pokud z důvodů přenositelnosti potřebujete použít existující názvy funkcí, můžete tato upozornění vypnout. Funkce jsou stále k dispozici v knihovně pod jejich původními názvy.
Pokud chcete pro tyto funkce vypnout upozornění na vynulování, definujte makro preprocesoru _CRT_NONSTDC_NO_WARNINGS . Toto makro můžete definovat na příkazovém řádku zahrnutím možnosti /D_CRT_NONSTDC_NO_WARNINGS .
Nezabezpečené funkce knihovny CRT
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.
Společnost Microsoft už nepoužívá některé funkce a globální funkce standardní knihovny CRT a C++, protože jsou k dispozici bezpečnější verze. Většina zastaralých funkcí umožňuje nezkontrolovaný přístup ke čtení nebo zápisu do vyrovnávacích pamětí. Jejich zneužití může vést k závažným problémům se zabezpečením. Kompilátor pro tyto funkce vydá upozornění na vyněcování a navrhne upřednostňovanou funkci.
Pokud chcete tento problém vyřešit, doporučujeme místo toho použít funkci nebo safe-version proměnnou. Někdy to není možné, kvůli přenositelnosti nebo zpětné kompatibilitě. Pečlivě ověřte, že není možné, aby v kódu došlo k přepsání nebo přečtení vyrovnávací paměti. Potom můžete upozornění vypnout.
Pokud chcete pro tyto funkce v CRT vypnout upozornění na vynulování, definujte _CRT_SECURE_NO_WARNINGS .
Pokud chcete vypnout upozornění na zastaralé globální proměnné, definujte _CRT_SECURE_NO_WARNINGS_GLOBALS .
Další informace o těchto zastaralých funkcích a globálních funkcích najdete v tématu Funkce zabezpečení v knihovnách CRT a Sejf: Standardní knihovna C++.
Nezabezpečené funkce standardní knihovny
'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'
V Visual Studio 2015 se toto upozornění zobrazí v sestaveních ladění, protože některé funkce šablony standardní knihovny C++ neschováují správnost parametrů. Často je to proto, že funkce nemá k dispozici dostatek informací ke kontrole meze kontejneru. Nebo, protože iterátory mohou být nesprávně použity s funkcí . Toto upozornění vám pomůže tyto funkce identifikovat, protože mohou být zdrojem vážných bezpečnostních problémů v programu. Další informace najdete v tématu Kontrola iterátorů.
Toto upozornění se například zobrazí v režimu ladění, pokud předáte ukazatel na prvek místo std::copy prostého pole. Pokud chcete tento problém vyřešit, použijte vhodně deklarované pole, aby knihovna kontroloval rozsahy polí a kontroloval meze.
// 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
}
V jazyce C++14 bylo aktualizováno několik standardních algoritmů knihovny, které mají verze s "duálním rozsahem". Pokud používáte verze se dvěma rozsahy, druhý rozsah poskytuje potřebnou kontrolu meze:
// 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;
}
Tento příklad ukazuje několik dalších způsobů, jak lze standardní knihovnu použít ke kontrole použití iterátoru, a pokud je použití nezaškrtnuté, může být nebezpečné:
// 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);
}
Pokud jste ověřili, že váš kód nemůže mít chybu přetečení vyrovnávací paměti, můžete toto upozornění vypnout. Pokud chcete pro tyto funkce vypnout upozornění, definujte _SCL_SECURE_NO_WARNINGS .
Povolené kontrolované iterátory
K chybě C4996 může dojít také v případě, že používáte kontrolovaný iterátor, pokud je definovaný _ITERATOR_DEBUG_LEVEL jako 1 nebo 2. Pro sestavení v režimu ladění je ve výchozím nastavení nastavená na hodnotu 2 a pro prodejní buildy je nastavená na hodnotu 0. Další informace najdete v tématu Kontrola iterátorů.
// 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
}
Nezabezpečený kód MFC nebo ATL
K chybě C4996 může dojít, pokud používáte funkce MFC nebo ATL, které byly z bezpečnostních důvodů zastaralé.
Pokud chcete tento problém vyřešit, důrazně doporučujeme, abyste kód změnili tak, aby místo toho používejte aktualizované funkce.
Informace o tom, jak tato upozornění potlačit, najdete v tématu _AFX_SECURE_NO_WARNINGS .
Zastaralé funkce a proměnné CRT
This function or variable has been superseded by newer library or operating system functionality. Consider using new_item instead. See online help for details.
Některé funkce knihovny a globální proměnné jsou zastaralé. Tyto funkce a proměnné je možné odebrat v budoucí verzi knihovny. Kompilátor pro tyto položky vydá upozornění na vyněcování a navrhne upřednostňovanou alternativu.
Pokud chcete tento problém vyřešit, doporučujeme změnit kód tak, aby se používá navrhovaná funkce nebo proměnná.
Pokud chcete u těchto položek vypnout upozornění na vynulování, definujte _CRT_OBSOLETE_NO_WARNINGS . Další informace najdete v dokumentaci k zastaralé funkci nebo proměnné.
Chyby zařazování v kódu CLR
K chybě C4996 může dojít také při použití knihovny zařazování CLR. V tomto případě je C4996 chybou, nikoli upozorněním. K této chybě dochází v případě, marshal_as že použijete k převodu mezi dvěma datovými typy, které marshal_as. Tato chyba se může zobrazit také v případě, že knihovna zařazování nepodporuje převod. Další informace o knihovně zařazování najdete v tématu Přehled zařazování v jazyce C++.
Tento příklad generuje C4996, protože zařazovací knihovna vyžaduje kontext pro převod z typu System::String na const 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;
}
Příklad: uživatelem definovaná vystaralá funkce
Můžete použít deprecated atribut ve vlastním kódu k upozornění volajících, když už nedoporučujete používat určité funkce. V tomto příkladu se C4996 generuje na dvou místech: jeden pro řádek, na kterém je vystaralá funkce deklarována, a jednu pro řádek, kde je funkce použita.
// 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
}