is your code portable?

Когда я пытаюсь разобраться в новом коде - я беру свой любимый компилятор и пытаюсь пофиксить (или хотя-бы рассмотреть) большинство предупреждений, которые он выдает. Потом выворачиваю уровень выдачи предупреждений на максимум и всё начинаю сначала.

gcc -Wall -W -Wextra -Weff-c++
gcc --help=warnings # и еще штук 20 из этого списка :]

Сам я это делаю, чтобы смотреть в чужой код было веселее. Побочным эффектом получается более переносимый (а часто и более корректный) код.

Сегодня рассмотрим пару предупреждений, которые мне выкопал gcc на реальном коде, который у нас (пока) собирается только под винду. Для этого я собрал кросс-компилятор mingw32-gcc и попытался его заюзать.

Пример 1:

/*
* warning: operation on 'block_size' may be undefined
*/
block_size = ((block_size << 1) < block_size) ? 0: (block_size <<= 1);
/*
* В одном выражении переменнй 'block_size' присваивается 2 (одинаковых) значения:
* block_size = ... (block_size <<= 1);
*
* Кстати, с '(block_size << 1) < block_size' тоже надо быть осторожным:
* компилятор может счесть целочисленное переполнение неопределенным поведением
* (в gcc отключается через -fwrapv) и выполнять только false ветвь.
*/

Пример 2:

// warning: left-hand operand of comma expression has no effect
if (hRoot == 0 ||
lpSubKey == NULL,
lpValue == NULL)
{
return FALSE;
}
/*
* С виду всё хорошо, но ',' во второй строке делает выражение очень веселым :]
* Предупреждение говорит, что всё, что до запятой не имеет никакой силы.
*/

Сами ошибки, конечно, не являются виндоспецифичными, но они зарыты посреди непортабельного кода. Его хотелось бы компилировать чем-то более параноидальным, чем MSVS. Как видим, у gcc неплохо получается.

Как бонус - реже коммитим код, который не компилируется только под виндой :]

Posted on September 29, 2011
comments powered by Disqus