пятница, 25 июня 2010 г.

Операторные скобки, египетские и не очень

У нас в проекте не существует Coding Style. Это конечно плохо, но тут вопрос программистского самосознания о том, что считать правильным, а что никогда не применять, потому что плохо.

Вот один из свежих конфликтов связан с операторными скобками для функций.

В коде я предпочитаю использовать египетские скобки, потому что они экономят размер кода по вертикали. Это ведь не справедливо, что стандартный экран имеет 80 символов в ширину и только 25 строк по высоте. :) 80 символов мне хватает почти всегда.

Проблема заключается в следующем:
1: void hello()
{
 printf("hello world\n");
}
Можно так:
2: void hello() {
 printf("hello world\n");
}
А можно даже так (только c++)
3: void hello() try {
 printf("hello world\n");
} catch(...) {
 ...
}

Последний вариант конечно экономит один уровень табуляции в каждой строке функции, но помоему является достаточно бесполезной фичей, за исключением конструкторов классов, в которых он позволяет обработать исключения при инициализации. Только там его и следует использовать. Использование исключений - вообще является спорным моментом, в стандарте кодирования Googlе они, например, вообще запрещены, чего не одобряю. Исключения, по моему мнению, очень мощная вещь. Но, как и любой другой очень мощной вещью, пользоваться ими надо осторожно и умеренно. При осторожном и умеренном использовании не возникает никакой необходимости обрабатывать исключения в каждой функции, и такая проблема - как лишняя табуляция от блока try - стоять вообще не должна.

Но я отвлекся. Вернемся к вариантам 1 и 2. Я долгое время объяснял свою приверженность варианту 1 тем, что прототип функции - понятие достаточно растяжимое, чтобы захламлять эту строку вещами, к ней не относящимися. Так же я поступаю например с блоками if, в том случае если условие достаточно сложное и скобка после условия не достаточно видна.

Но недавно меня осенило очень простое объяснение. Суть в том, что void hello() - это прототип, а { printf("hello world\n"); } - это тело. Если прототип у нас находится отдельно от тела - мы легко можем скопировать строку и вставить ее во включаемый файл. Нам будет необходимо лишь добавить точку с запятой. Если же мы будем захламлять строку прототипа дополнительными конструкциями типа 'try' и '{', то мы лишимся такой удобной возможности просто скопировать в случае, например, изменения списка параметров.

Остается еще захламление строки прототипа неймспейсами и именами классов, но тут уж ничего не поделаешь. Надо с этим как-то жить.

Мой кодинг стайл: обычные скобки для функций, египетские для логики.