понедельник, 15 августа 2011 г.

Автоматический выбор типа


В библиотеке Boost есть набор средств для выбора типов. Например, можно выбрать наименьший тип с не менее чем N бит:
typedef boost::int_t<N>::least my_int_t;
Или тип, который точно сможет уместить в себя все числа в диапазоне от 0 до V:
typedef boost::int_max_value_t<V>::last my_int_t;
Или ещё целый беззнаковый тип, который может работать с числами от 0 до V и, при этом, самый быстрый на данной платформе:
typedef boost::uint_value_t<V>::fast my_uint_t;

Полный список можно посмотреть в документации.

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

ЭЛВИС-НеоТек нанимает на работу

Компания ЭЛВИС-НеоТек приглашает на работу разработчиков.

вторник, 9 августа 2011 г.

ternary operator (?:)

Интересный факт: тернарный оператор (?:) может стоять не только в правой части выражения, но и в левой. Пример:
int a = 5; int b = 10;
(a > b ? a : b) = 100; // большему из a и b присвоим 100
cout << "a=" << a << " b=" << b << endl;

// result will be: a=5 b=100

пятница, 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() );

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