пятница, 5 августа 2011 г.

Безопасны ли безопасные функции в Windows?

Visual C++ при компиляции ANSI функций работы со строками постоянно выдает предупреждение о том, что есть более безопасные версии и использовать нужно именно их. Однако, по набору параметров они могут вовсе не отличаться, что не позволяет заметить разницу на этапе компиляции. Например, имеем следующий код:
int main(int argc, char *argv[])
{
    const char* stLine = "s=Media Presentation\n";

    std::vector<char> param(1024);

    _snscanf( stLine, 20, "s=%[^\r\n]", &param[0] );

    return 0;
}
Код этот отлично работает, но при компиляции выдается предупреждение, что стоит использовать фунуцию _snscanf_s. Смотрим документацию и на первый взгляд отличий никаких. Хорошо, меняем на _snscanf_s:
_snscanf_s( stLine, 20, "s=%[^\r\n]", &param[0] );
В результате программа отлично компилируется теперь уже без предупреждений, но падает в процессе выполнения. В чем же дело?

Если почитать документацию более внимательно, то находим следующее небольшое замечание:
The buffer size parameter is required with the type field characters c, C, s, S, and [. For more information, see scanf Type Field Characters.

Это означает, что теперь после каждого строкового параметра нужно передавать размер буфера, т. е. код должен выглядеть следующим образом:
_snscanf_s( stLine, 20, "s=%[^\r\n]", &param[0], param.size() );

В этой ситуации плохо то, что функция стала работать хуже, чем небезопасный оригинал. Я ни в коем случае не агитирую за использование опасных фукнций, просто нужно учитывать, что механическая замена одних на другие приводит к ошибкам.

Комментировать в ВКонтакте