Инструменты пользователя

Инструменты сайта



// MinGW и локали

Если коротко, то всё, что связано с std::locale в MinGW не работает. Точка.

Зато вполне себе работает функционал из Си:

std::locale::global(std::locale("")); // не установит текущую локаль
setlocale(LC_ALL, ""); // установит текущую локаль, у меня это Russian_Russia.Cp1251

// Онлайн компиляторы C/C++ и не только

Иногда нужно быстро проверить работоспособность какой-то идеи или алгоритма. Хорошо, когда у вас Linux и какая-то система из семейства Unix с установленным компилятором (имхо, в 90% случаев это будет правдой), вам просто нужно открыть консоль вызвать vim/emacs/joe/mcedit/etc набросать программку и вызвать компилятор. Но иногда вы в гостях/командировке/интернет-кафе, в общем тогда, когда компилятора нет под рукой, но есть доступ в интернет. Тут помогут онлайн-компиляторы.

// Binary Logic Bit Operations In C and C++

На заметку: http://www.somacon.com/p125.php там же удобный калькулятор для перевода констант между четырмя популярными системами счисления (BIN, OCT, HEX, DEC)

// MinGW32: как избавиться от зависимостей в виде libgcc_*.dll и libstdc++-*.dll?

Почти всегда программа (особенно маленькие и без инсталлятора) для win распространяется в виде законченного бандла со всеми DLL и прочим потребством. Проблема, что программа, скомпилированная примерно так:

i486-mingw32-g++ -o foo.exe foo.cpp

как минимум требует двух DLL: libgcc_*.dll и libstdc++-*.dll, что бы избавится от них можно использовать опции -static-libgcc и -static-libstdc++:

i486-mingw32-g++ -static-libgcc -static-libstdc++ -o foo.exe foo.cpp

// Using Internet Sockets

Работая над программой столкнулся с проблемой в части функционала сокетов, пока искал в интернетах возможный пути решения проблемы, натолкнулся на интересное руководство: Beej's Guide to Network Programming. Using Internet Sockets

Руководство доступно в в различных форматах (по ссылке выше можно найти подходящие), вот самые удобные, на мой взгляд:

Руководство переведено на несколько языков, но русского среди них нет, так что если кому не терпится - переводите, будет, по крайней мере, от меня, большое спасибо и пару-тройку бутылочек пива, если окажетесь в зоне досягаемости :)

Стоит отметить, что помимо всяких Linux/Unix есть информация и про Windows, в частности будет полезно при разработке кроссплатформенных сетевых приложений.

Ещё, среди кучи ссылок, в тексте обнаружилась такая полезная: UNIX Socket FAQ - тоже кладезь знаний.

В дополнение, книжка «Linux Socket Programming by Example», можно купить на Амазоне: http://www.amazon.com/Linux-Socket-Programming-Example-Warren/dp/0789722410 или:

// Как узнать каким компилятором мы компилируемся?

Не всё делается одинаково во всех компиляторах, не на всех платформах, приходится временами городить хитрые конструкции из #if/#elif/#endif. Случайно наткнулся на шпаргалку, в которой описано, какие директивы препроцессора предопределяют конкретные компиляторы: http://sourceforge.net/p/predef/wiki/Compilers/

С того же ресурса:

А так же определение порядка байтов: http://sourceforge.net/p/predef/wiki/Endianness/

Другие ссылки на эту тематику:

// The Function Pointer Tutorials

Хорошее руководство: http://www.newty.de/fpt/index.html

PDF версия: http://www.newty.de/fpt/zip/e_fpt.pdf

Там же, прицепом: «Callback Implementations in C++»

// hypot

hypot(x, y) создан, что бы не звать sqrt(x*x + y*y)

Подробности:

// Robust Design Techniques for C Programs - на заметку

http://freetype.sourceforge.net/david/reliable-c.html

UPD 2014-06-09: сменил ссылку, прошлая убилась

// winsock2: неблокирующийся сокет

    unsigned long arg = 1;
    ioctlsocket(sockfd, FIONBIO, &arg);

в Linux:

    int arg = fcntl(sockfd, F_GETFL, NULL);
    arg |= O_NONBLOCK;
    fcntl(sockfd, F_SETFL, arg);

или универсальная функция:

void setSockNonblock(int sockfd)
{
#ifdef WIN32
    unsigned long arg = 1;
    ioctlsocket(sockfd, FIONBIO, &arg);
#else
    int arg = fcntl(sockfd, F_GETFL, NULL);
    arg |= O_NONBLOCK;
    fcntl(sockfd, F_SETFL, arg);
#endif
}

// inet_aton для windows

Если коротко: функиця заполняет структуру типа in_addr, преобразуя сведения о хосте из строкового представления.

У winsock2 нет такой функции. Есть более продвинутый аналог inet_pton, в POSIX он тоже есть, да вот только mingw про неё в windows не знает. Пичалька.

Поэтому делаем примерно следующее:

#ifdef WIN32
static int inet_aton(const char *cp, struct in_addr *inp)
{
    if (cp == 0 || inp == 0)
    {
        return -1;
    }
 
    unsigned long addr = inet_addr(cp);
    if (addr == INADDR_NONE || addr == INADDR_ANY)
    {
        return -1;
    }
 
    inp->s_addr = addr;
}
#endif

не верх совершенства и корректности, но для моих целей работало.

// Таймеры в Windows

Внезапно, правда? :)

Но волей судеб нужно было портировать программку, в которой использовался nanosleep(2). И…

Для внезапно стало откровением: В WINDOWS НЕТ ТАЙМЕРОВ ВЫСОКОГО РАЗРЕШЕНИЯ. А есть только по сути хаки и вызов Sleep, с минимальным промежутком в 10мс.

Наиболее часто рекомендуемый вариант:

void sleep_nsec(int64_t interval)
{
    int64_t time1 = 0, time2 = 0, sysFreq = 0;
 
    QueryPerformanceCounter((LARGE_INTEGER *) &time1);
    QueryPerformanceFrequency((LARGE_INTEGER *) &sysFreq);
 
    do
    {
        QueryPerformanceCounter((LARGE_INTEGER *) &time2);
    } while(((time2-time1)*1000.0*1000.0/(double)(sysFreq)) < interval);
}

Но тут мы упираем процессор в полку. Есть вариант с использованием select, но, по отзывам, он так же может ждать не менее 10мс.

Т.е., по сути, это единственный вариант для Windows, да ещё и не лишённый глюков: почти все процессоры уже умеют автоматическое понижение частоты… Чуете? Пока работает цикл, значение sysFreq может измениться (поправьте меня, если я не прав) и время потекло.

Кроме того, наткнулся на статью:
http://www.codeproject.com/KB/system/timers_intro.aspx - Timers Tutorial

Описываются различные вариант таймеров: стандартные win32, мультимедийные, Waitable Timers (не знаю как лучше перевести на русский язык), Queue Timers. Но опять таки, все периоды - миллисекунды.

// Си, прекрасное

http://eli.thegreenplace.net/2011/02/15/array-initialization-with-enum-indices-in-c-but-not-c/ - это воистину прекрасно! Использовать enum для именованной инициализации массива. Можно делать в C99, не работает в C++

Ну и ссылки, на правах мемориза:

  • http://www.advancedlinuxprogramming.com/alp-folder - по названию сайта уже понятно, что это такое :) книжка «Advanced Linux Programming» в сободном доступе. На просторах интернета встречается русский перевод, можно поискать.
  • http://mij.oltrelinux.com/devel/unixprg/ - «UNIX programming examples» - примеры кода на Си для unix, в частности - сокеты, IPC, потоки.