Sobrecargas de modelo seguras

A Microsoft preteriu muitas funções CRT (biblioteca de runtime C) em favor de versões com segurança aprimorada. Por exemplo, strcpy_s é o substituto mais seguro de strcpy. As funções preteridas são as origens comuns de bugs de segurança, pois não impedem operações que podem substituir a memória. Por padrão, o compilador gerará um aviso de substituição quando você usar uma dessas funções. A CRT fornece sobrecargas de modelo do C++ para essas funções para ajudar a facilitar a transição para as variantes mais seguras.

Por exemplo, este snippet de código gera um aviso porque strcpy foi preterido:

char szBuf[10];
strcpy(szBuf, "test"); // warning: deprecated

O aviso de substituição existe para informá-lo de que o código pode não ser seguro. Se você verificou que o código não pode substituir a memória, você tem várias opções. Você pode optar por ignorar o aviso, pode definir o símbolo _CRT_SECURE_NO_WARNINGS antes das instruções include para cabeçalhos CRT para suprimir o aviso ou pode atualizar o código para usar strcpy_s:

char szBuf[10];
strcpy_s(szBuf, 10, "test"); // security-enhanced _s function

As sobrecargas de modelo fornecem mais opções. Se você definir _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES como 1, ele habilitará sobrecargas de modelo de funções CRT padrão que chamam as variantes mais seguras automaticamente. Se _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES for 1, nenhuma alteração no código é necessária. Nos bastidores, a chamada para strcpy é alterada para uma chamada para strcpy_s com o argumento de tamanho fornecido automaticamente.

#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

// ...

char szBuf[10];
strcpy(szBuf, "test"); // ==> strcpy_s(szBuf, 10, "test")

A macro _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES não afeta as funções que usam uma contagem, como strncpy. Para habilitar as sobrecargas de modelo para funções de contagem, defina _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT como 1. Antes de fazer isso, no entanto, certifique-se de que seu código passa a contagem de caracteres, não o tamanho do buffer (um erro comum). Além disso, um código que grave explicitamente um terminador nulo ao final do buffer após a chamada de função não é necessário se a variante segura for chamada. Se você precisar de comportamento de truncamento, consulte _TRUNCATE.

Observação

A macro _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT requer que _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES também seja definida como 1. Se _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT for definida como 1 e _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES for definida como 0, o aplicativo não executará sobrecargas de modelo.

Quando você define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES como 1, ele permite sobrecargas de modelo das variantes seguras (nomes terminando em "_s"). Nesse caso, se _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES for 1, uma pequena alteração deverá ser feita no código original:

#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1

// ...

char szBuf[10];
strcpy_s(szBuf, "test"); // ==> strcpy_s(szBuf, 10, "test")

Somente o nome da função precisa ser alterado (adicionando “_s”); a sobrecarga de modelo se encarrega de fornecer o argumento de tamanho.

Por padrão, _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES e _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT são definidas como 0 (desabilitada) e _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES é definida como 1 (ativada).

As sobrecargas de modelo só funcionam para matrizes estáticas. Buffers alocados dinamicamente exigem outras alterações no código-fonte. Revisitando os exemplos anteriores:

#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

// ...

char *szBuf = (char*)malloc(10);
strcpy(szBuf, "test"); // still deprecated; change it to
                       // strcpy_s(szBuf, 10, "test");

E este exemplo:

#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1

// ...

char *szBuf = (char*)malloc(10);
strcpy_s(szBuf, "test"); // doesn't compile; change it to
                         // strcpy_s(szBuf, 10, "test");

Confira também

Recursos de segurança no CRT
Arquivos .lib de runtime do C (CRT) e Biblioteca Padrão (STL) do C++