Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il codice usa una funzione, un membro della classe, una variabile o un typedef contrassegnato come deprecato. I simboli sono deprecati usando un __declspec(deprecated) modificatore o l'attributo C++14 [[deprecated]] . Il messaggio di avviso C4996 effettivo viene specificato dal modificatore o dall'attributo deprecated della dichiarazione.
Importante
Questo avviso è sempre un messaggio intenzionale dell'autore del file di intestazione che dichiara il simbolo. Non usare il simbolo deprecato senza comprendere le conseguenze.
Osservazioni:
Molte funzioni, funzioni membro, modelli di funzione e variabili globali nelle librerie di Visual Studio sono deprecate. Alcune, ad esempio POSIX e funzioni specifiche di Microsoft, sono deprecate perché ora hanno un nome preferito diverso. Alcune funzioni della libreria di runtime C sono deprecate perché non sono sicure e hanno una variante più sicura. Altri sono deprecati perché sono obsoleti. I messaggi di deprecazione in genere includono una sostituzione suggerita per la funzione deprecata o la variabile globale.
L'opzione del /sdl compilatore (Abilita controlli di sicurezza aggiuntivi) eleva questo avviso a un errore.
Disattivare l'avviso
Per risolvere un problema C4996, in genere è consigliabile modificare il codice. Usare invece le funzioni suggerite e le variabili globali. Se è necessario usare le funzioni o le variabili esistenti per motivi di portabilità, è possibile disattivare l'avviso.
Disattivare l'avviso per una riga di codice specifica
Per disattivare l'avviso per una riga di codice specifica, usare il warning pragma , #pragma warning(suppress : 4996).
Disattivare l'avviso all'interno di un file
Per disattivare l'avviso all'interno di un file per tutti gli elementi seguenti, usare il pragma di avviso , #pragma warning(disable : 4996).
Disattivare l'avviso nelle compilazioni della riga di comando
Per disattivare l'avviso a livello globale nelle compilazioni della riga di comando, usare l'opzione della /wd4996 riga di comando.
Disattivare l'avviso per un progetto in Visual Studio
Per disattivare l'avviso per un intero progetto nell'IDE di Visual Studio:
Aprire la finestra di dialogo Pagine delle proprietà per il progetto. Per informazioni su come usare la finestra di dialogo Pagine delle proprietà, vedere Pagine delle proprietà.
Selezionare la pagina delle proprietà Proprietà> di configurazioneC/C++>Avanzate.
Modificare la proprietà Disabilita avvisi specifici per aggiungere
4996. Scegliere OK per applicare le modifiche.
Disabilitare l'avviso usando macro del preprocessore
È anche possibile usare macro di preprocessore per disattivare determinate classi specifiche di avvisi di deprecazione usati nelle librerie. Queste macro sono descritte di seguito.
Per definire una macro del preprocessore in Visual Studio:
Aprire la finestra di dialogo Pagine delle proprietà per il progetto. Per informazioni su come usare la finestra di dialogo Pagine delle proprietà, vedere Pagine delle proprietà.
Espandere Proprietà > di configurazione Preprocessore C/C++>.
Nella proprietà Definizioni preprocessore aggiungere il nome della macro. Scegliere OK per salvare e quindi ricompilare il progetto.
Per definire una macro solo in file di origine specifici, aggiungere una riga come #define EXAMPLE_MACRO_NAME prima di qualsiasi riga che includa un file di intestazione.
Ecco alcune delle origini comuni degli avvisi e degli errori C4996:
Nomi di funzione POSIX
Il nome POSIX per questo elemento è deprecato. Usare invece il nome conforme a ISO C e C++:
new-name. Per informazioni dettagliate, vedere la Guida online.
Microsoft ha rinominato alcune funzioni di libreria specifiche di POSIX e Microsoft in CRT in modo che siano conformi ai vincoli C99 e C++03 sui nomi riservati e globali definiti dall'implementazione. Solo i nomi sono deprecati, non le funzioni stesse. Nella maggior parte dei casi, al nome della funzione è stato aggiunto un carattere di sottolineatura iniziale per creare un nome conforme. Il compilatore genera un avviso di deprecazione per il nome della funzione originale e suggerisce il nome preferito.
Per risolvere questo problema, in genere è consigliabile modificare il codice in modo da usare i nomi di funzione suggeriti. Tuttavia, i nomi aggiornati sono specifici di Microsoft. Se è necessario usare i nomi di funzione esistenti per motivi di portabilità, è possibile disattivare questi avvisi. Le funzioni sono ancora disponibili nella libreria con i nomi originali.
Per disattivare gli avvisi di deprecazione per queste funzioni, definire la macro _CRT_NONSTDC_NO_WARNINGSdel preprocessore . È possibile definire questa macro nella riga di comando includendo l'opzione /D_CRT_NONSTDC_NO_WARNINGS.
Funzioni della libreria CRT unsafe
Questa funzione o variabile potrebbe non essere sicura. Prendere invece in considerazione l'uso
safe-versiondi . Per disabilitare la deprecazione, usare _CRT_SECURE_NO_WARNINGS. Per informazioni dettagliate, vedere la Guida online.
Microsoft ha deprecato alcune funzioni della libreria standard CRT e C++ e globali perché sono disponibili versioni più sicure. La maggior parte delle funzioni deprecate consente l'accesso in lettura o scrittura non selezionato ai buffer. L'uso improprio può causare gravi problemi di sicurezza. Il compilatore genera un avviso di deprecazione per queste funzioni e suggerisce la funzione preferita.
Per risolvere questo problema, è consigliabile usare invece la funzione o la variabile safe-version . In alcuni casi non è possibile, per motivi di portabilità o compatibilità con le versioni precedenti. Verificare attentamente che non sia possibile che nel codice si verifichi una sovrascrittura o una sovralettura del buffer. È quindi possibile disattivare l'avviso.
Per disattivare gli avvisi di deprecazione per queste funzioni in CRT, definire _CRT_SECURE_NO_WARNINGS.
Per disattivare gli avvisi relativi alle variabili globali deprecate, definire _CRT_SECURE_NO_WARNINGS_GLOBALS.
Per altre informazioni su queste funzioni deprecate e sulle globalità, vedere Funzionalità di sicurezza nelle librerie CRT e safe: libreria standard C++.
Funzioni della libreria standard unsafe
'std::
function_name::_Unchecked_iterators::_Deprecate' Chiamata a std::function_namecon parametri che potrebbero non essere sicuri. Questa chiamata si basa sul chiamante per verificare che i valori passati siano corretti. Per disabilitare questo avviso, usare -D_SCL_SECURE_NO_WARNINGS. Vedere la documentazione su come usare Visual C++ 'Checked Iterators'
In Visual Studio 2015 questo avviso viene visualizzato nelle compilazioni di debug perché alcuni modelli di funzioni della libreria standard C++ non controllano la correttezza dei parametri. Spesso è dovuto al fatto che non sono disponibili informazioni sufficienti per la funzione per controllare i limiti del contenitore. In alternativa, poiché gli iteratori possono essere usati in modo non corretto con la funzione . Questo avviso consente di identificare queste funzioni, perché possono essere una fonte di gravi problemi di sicurezza nel programma. Per altre informazioni, vedere Iteratori verificati.
Ad esempio, questo avviso viene visualizzato in modalità debug se si passa un puntatore di elemento a std::copy, invece di una matrice normale. Per risolvere questo problema, usare una matrice dichiarata in modo appropriato, in modo che la libreria possa controllare gli extent della matrice ed eseguire il controllo dei limiti.
// 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
}
Diversi algoritmi di libreria standard sono stati aggiornati per avere versioni "dual range" in C++14. Se si usano le versioni a doppio intervallo, il secondo intervallo fornisce il controllo dei limiti necessario:
// 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;
}
Questo esempio illustra diversi modi in cui la libreria standard può essere usata per controllare l'utilizzo dell'iteratore e quando l'utilizzo non selezionato può essere pericoloso:
// 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);
}
Se si è verificato che il codice non può avere un errore di overrun del buffer, è possibile disattivare questo avviso. Per disattivare gli avvisi per queste funzioni, definire _SCL_SECURE_NO_WARNINGS.
Iteratori verificati abilitati
C4996 può verificarsi anche se non si usa un iteratore controllato quando _ITERATOR_DEBUG_LEVEL viene definito come 1 o 2. È impostato su 2 per impostazione predefinita per le compilazioni in modalità di debug e su 0 per le build di vendita al dettaglio. Per altre informazioni, vedere Iteratori verificati.
// 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
}
Codice MFC o ATL non sicuro
C4996 può verificarsi se si usano funzioni MFC o ATL deprecate per motivi di sicurezza.
Per risolvere questo problema, è consigliabile modificare il codice in modo da usare le funzioni aggiornate.
Per informazioni su come eliminare questi avvisi, vedere _AFX_SECURE_NO_WARNINGS.
Funzioni e variabili CRT obsolete
Questa funzione o variabile è stata sostituita da una libreria o una funzionalità del sistema operativo più recente. Prendere invece in considerazione l'uso
new_itemdi . Per informazioni dettagliate, vedere la Guida online.
Alcune funzioni di libreria e variabili globali sono deprecate come obsolete. Queste funzioni e variabili possono essere rimosse in una versione futura della libreria. Il compilatore genera un avviso di deprecazione per questi elementi e suggerisce l'alternativa preferita.
Per risolvere questo problema, è consigliabile modificare il codice in modo da usare la funzione o la variabile suggerita.
Per disattivare gli avvisi di deprecazione per questi elementi, definire _CRT_OBSOLETE_NO_WARNINGS. Per altre informazioni, vedere la documentazione relativa alla funzione o alla variabile deprecata.
Marshalling degli errori nel codice CLR
C4996 può verificarsi anche quando si usa la libreria di marshalling CLR. In questo caso, C4996 è un errore, non un avviso. L'errore si verifica quando si usa marshal_as per eseguire la conversione tra due tipi di dati che richiedono una marshal_context classe. È anche possibile ricevere questo errore quando la libreria di marshalling non supporta una conversione. Per altre informazioni sulla libreria di marshalling, vedere Panoramica del marshalling in C++.
Questo esempio genera l'errore C4996 perché la libreria di marshalling richiede un contesto per la conversione da un System::String oggetto a un oggetto 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;
}
Esempio: Funzione deprecata definita dall'utente
È possibile usare l'attributo nel proprio codice per avvisare i chiamanti quando non si consiglia più l'uso deprecated di determinate funzioni. In questo esempio, C4996 viene generato in due posizioni: una per la riga in cui viene dichiarata la funzione deprecata e una per la riga in cui viene usata la funzione.
// 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
}