Temat: warning C4996: This function or variable may be unsafe

Jeżeli korzystamy w Visual Studio z funkcji takich jak scanf, fscanf, fopen, możemy otrzymać takie ostrzeżenie:

warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Visual Studio ostrzega nas w ten sposób, że te funkcje mogą być niebezpieczne.

Na czym polega niebezpieczeństwo?

Jeżeli wczytując dane do tablicy znaków:

char napis[20];
scanf("%s", napis);

wpiszemy więcej znaków niż przewidzieliśmy deklarując tablicę, nastąpi przepełnienie bufora, czego efektem będzie błąd podczas uruchomienia programu.

Nawet jeżeli w programie nie mamy takiej sytuacji z wczytywaniem tablicy, Visual i tak doczepi się do każdej funkcji scanf.

Visual podpowiada nam, aby użyć w zamian funkcji scanf_s, która posiada dodatkowe zabezpieczenia przed takimi sytuacjami.

My jednak wolimy pozostać przy "zwykłych" funkcjach typu scanf, gdyż ich Microsoftowe odpowiedniki sprawiają, że kod staje się mniej przenośny (nie będzie działał na innych systemach operacyjnych i kompilatorach).

Poza tym testując prosty program:

#include <stdio.h>

void main(void) {
    char napis[10];
    scanf_s("%s", napis);
    printf("%s", napis);
}

zauważyłem, że po wpisaniu "abc" nic nie zostało wyświetlone. Być może Visual aż tak dalece posunął się w swojej ostrożności, że zablokował mi całkowicie możliwość wczytywania danych smile

Dlatego aby wyciszyć ostrzeżenia o tym "niebezpieczeństwie" korzystamy z drugiego rozwiązania, jakie podpowiada nam kompilator, czyli makrodefinicji _CRT_SECURE_NO_WARNINGS (deklarujemy ją koniecznie na samym początku pliku z kodem źródłowym).

Natomiast przed przepełnieniem bufora zabezpieczamy się sami, podając w funkcji maksymalną liczbę znaków, jaką dopuszczamy wczytać do tablicy:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

void main(void) {
    char napis[10];
    scanf("%9s", napis);
    printf("%s", napis);
}

(pamiętamy, że w C tablica znaków, którą chcemy traktować jak napis musi się kończyć znakiem '\0', więc do tablicy char tab[10] możemy wczytać przez %s 9 znaków)