Pergunta

Sobre Compilador C++ do Visual Studio 2005, recebo o seguinte aviso quando meu código usa o abrir e tais chamadas.

1>foo.cpp(5) : warning C4996: 'fopen' was declared deprecated
1>        c:\program files\microsoft visual studio 8\vc\include\stdio.h(234) : see declaration of 'fopen'
1>        Message: 'This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

Como posso evitar isso?

Foi útil?

Solução

Parece que a Microsoft descontinuou muitas chamadas que usam buffers para melhorar a segurança do código.No entanto, as soluções que eles fornecem não são portáteis.De qualquer forma, se você não estiver interessado em usar a versão segura de suas chamadas (como fopen_s), você precisa colocar uma definição de _CRT_SECURE_NO_DEPRECATE antes dos arquivos de cabeçalho incluídos.Por exemplo:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

A diretiva do pré-processador também pode ser adicionada às configurações do seu projeto para afetá-la em todos os arquivos do projeto.Para fazer isso adicione _CRT_SECURE_NO_DEPRECATE para Propriedades do projeto -> Propriedades de configuração -> C/C++ -> Pré-processador -> Definições do pré-processador.

Outras dicas

Bem, você poderia adicionar um:

#pragma warning (disable : 4996)

antes de usar fopen, mas você já pensou em usar fopen_s como o aviso sugere?Ele retorna um código de erro que permite verificar o resultado da chamada de função.

O problema de apenas desabilitar avisos de funções obsoletas é que a Microsoft pode remover a função em questão em uma versão posterior do CRT, quebrando seu código (conforme declarado abaixo nos comentários, isso não acontecerá neste caso com fopen porque faz parte de os padrões ISO C e C++).

Isso é apenas a Microsoft sendo atrevida."Obsoleto" implica um recurso de linguagem que pode não ser fornecido em versões futuras da linguagem padrão/bibliotecas padrão, conforme decretado pelo comitê de padrões.Não significa, ou não deveria significar, "nós, unilateralmente, não achamos que você deva usá-lo", não importa quão bem fundamentado seja esse conselho.

Se o seu código for destinado a um sistema operacional diferente (como Mac OS X, Linux), você poderá usar o seguinte:

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif

Considere usar uma biblioteca de portabilidade como simplista ou o tempo de execução portátil apache.Geralmente, eles fornecem alternativas seguras e portáteis para chamadas como essas.Isso também é bom, porque essas chamadas inseguras estão obsoletas na maioria dos ambientes modernos.

Estou usando o VisualStdio 2008.Neste caso eu costumo definir Preprocessor Definitions

Menu \ Projeto \ [Nome do Projeto] Propriedades...Alt+F7

Se clicar neste menu ou pressionar Alt + F7 na janela do projeto, você poderá ver "Páginas de propriedades" janela.

Então veja o menu à esquerda da janela.

Propriedades de configuração \ C/C++ \ Pré-processador

Em seguida, adicione _CRT_SECURE_NO_WARNINGS para \ Definições de pré-processador.

Se você quiser que ele seja usado em muitas plataformas, você pode usar definições comentadas como:

#if defined(_MSC_VER) || defined(WIN32)  || defined(_WIN32) || defined(__WIN32__) \
                        || defined(WIN64)    || defined(_WIN64) || defined(__WIN64__) 

        errno_t err = fopen_s(&stream,name, "w");

#endif

#if defined(unix)        || defined(__unix)      || defined(__unix__) \
                        || defined(linux)       || defined(__linux)     || defined(__linux__) \
                        || defined(sun)         || defined(__sun) \
                        || defined(BSD)         || defined(__OpenBSD__) || defined(__NetBSD__) \
                        || defined(__FreeBSD__) || defined __DragonFly__ \
                        || defined(sgi)         || defined(__sgi) \
                        || defined(__MACOSX__)  || defined(__APPLE__) \
                        || defined(__CYGWIN__) 

        stream = fopen(name, "w");

#endif

Para aqueles que usam a versão Visual Studio 2017, parece que a definição do pré-processador necessária para executar operações inseguras mudou.Use em vez disso:

#define _CRT_SECURE_NO_WARNINGS

Ele será compilado então.

Muitas das funções seguras da Microsoft, incluindo fopen_s(), fazem parte do C11, portanto devem ser portáveis ​​agora.Você deve perceber que as funções seguras diferem em comportamentos de exceção e, às vezes, em valores de retorno.Além disso, você precisa estar ciente de que, embora essas funções sejam padronizadas, é um opcional parte do padrão (Anexo K) que pelo menos a glibc (padrão no Linux) e a libc do FreeBSD não implementam.

No entanto, lutei contra esse problema por alguns anos.Publiquei um conjunto maior de macros de conversão aqui., Para o seu problema imediato, coloque o seguinte código em um arquivo de inclusão e inclua-o em seu código-fonte:

#pragma once
#if !defined(FCN_S_MACROS_H)
   #define   FCN_S_MACROS_H

   #include <cstdio>
   #include <string> // Need this for _stricmp
   using namespace std;

   // _MSC_VER = 1400 is MSVC 2005. _MSC_VER = 1600 (MSVC 2010) was the current
   // value when I wrote (some of) these macros.

   #if (defined(_MSC_VER) && (_MSC_VER >= 1400) )

      inline extern
      FILE*   fcnSMacro_fopen_s(char *fname, char *mode)
      {  FILE *fptr;
         fopen_s(&fptr, fname, mode);
         return fptr;
      }
      #define fopen(fname, mode)            fcnSMacro_fopen_s((fname), (mode))

   #else
      #define fopen_s(fp, fmt, mode)        *(fp)=fopen( (fmt), (mode))

   #endif //_MSC_VER

#endif // FCN_S_MACROS_H

É claro que esta abordagem não implementa o comportamento de exceção esperado.

Eu também tive o mesmo problema.Quando tento adicionar a biblioteca opencv

#include <opencv\cv.h>

Não recebi um aviso, mas um erro.

error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    c:\program files (x86)\opencv\build\include\opencv2\flann\logger.h  

Também usei as diretivas do pré-processador conforme mencionado.Mas isso não resolveu o problema.

Eu resolvi fazendo o seguinte:

  • Vá para Propriedades -> C/C++ -> Cabeçalhos pré-compilados -> Escolha Não usar cabeçalhos pré-compilados no cabeçalho pré-compilado.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top