То, почему все еще C99, смешало объявления и код, не используемый в проектах открытого исходного кода C как ядро Linux или GNOME?
Мне действительно нравятся смешанные объявления и код, так как он делает код более читаемым и предотвращает трудно для наблюдения ошибок путем ограничения объема переменных к самому узкому. Это рекомендуется Google для C++.
Например, Linux требует, по крайней мере, GCC 3.2, и GCC 3.1 имеет поддержку смешанных объявлений и кода C99
Это старый вопрос, но я собираюсь предположить, что инерция является причиной того, что большинство этих проектов все еще используют правила объявлений ANSI C.
Однако есть ряд других возможностей, начиная от действительных до смешных:
Переносимость. Многие проекты с открытым исходным кодом работают в предположении, что педантичный ANSI C является наиболее портативным способом написания программного обеспечения.
Возраст. Многие из этих проектов предшествуют спецификации C99, и авторы могут предпочесть последовательный стиль кодирования.
Невежество. Программисты, предшествующие C99, не знают о преимуществах смешанных объявлений и кода. (Альтернативная интерпретация: разработчики полностью осознают потенциальные компромиссы и решают, что смешанные декларации и заявления не стоят усилий. Я категорически не согласен, но редко бывает, чтобы два программиста согласились с чем-либо.)
ФУД. Программисты рассматривают смешанные объявления и код как «C++ism» и не любят его по этой причине.
Вам не требуется смешанное объявление и код для ограничения области действия. Вы можете сделать:
{
int c;
c = 1;
{
int d = c + 1;
}
}
в C89. Что касается того, почему в этих проектах не использовались смешанные объявления (при условии, что это правда), то, скорее всего, это случай «Если все в порядке, не чините».
Нет причин менять код таким образом, а C99 по-прежнему широко не поддерживается компиляторами. В основном это касается портативности.
Может и не нужно, может, разделение хорошее? Я делаю это на C ++, в котором тоже есть эта функция.
Нет особых причин переписывать ядро Linux на внесите косметические изменения, не дающие прироста производительности.
Если кодовая база работает, зачем ее менять по косметическим причинам?
Нет никакой выгоды. Объявление всех переменных в начале функции (как в паскале) намного более понятно, в C89 вы также можете объявлять переменные в начале каждой области (пример внутри циклов), что одновременно практично и кратко.
Я не помню никаких запретов на это в руководстве по стилю кода ядра. Однако он говорит, что функции должны быть как можно меньше и делать только одно. Это объясняет, почему сочетание деклараций и кода встречается редко.
В небольшой функции объявление переменных в начале области действия действует как своего рода Introit , рассказывая вам кое-что о том, что произойдет вскоре после этого. В этом случае перемещение объявления переменной настолько ограничено, что оно, скорее всего, либо не окажет никакого эффекта, либо послужит для сокрытия некоторой информации о функциональности, так сказать, заталкивая зазывателя в толпу. Есть причина, по которой о прибытии короля объявили до того, как он вошел в комнату.
OTOH, функция, которая должна смешивать переменные и код для чтения, вероятно, слишком велика. Это один из признаков (наряду со слишком вложенными блоками, встроенными комментариями и другими вещами) того, что некоторые разделы функции необходимо абстрагировать в отдельные функции (и объявить статическими
, чтобы оптимизатор мог их встроить ).
Еще одна причина сохранить объявления в начале функций: если вам нужно изменить порядок выполнения операторов в коде, вы можете переместить переменную за пределы ее области видимости, не осознавая этого, поскольку область видимости переменной, объявленной в середина кода не видна в отступе (если вы не используете блок для отображения области действия). Это легко исправить, так что это просто раздражение, но новый код часто претерпевает такие преобразования, и раздражение может накапливаться.
И еще одна причина: у вас может возникнуть соблазн объявить переменную для получения кода возврата ошибки из функции, например:
void_func();
int ret = func_may_fail();
if (ret) { handle_fail(ret) }
Совершенно разумный поступок. Но:
void_func();
int ret = func_may_fail();
if (ret) { handle_fail(ret) }
....
int ret = another_func_may_fail();
if (ret) { handle_other_fail(ret); }
Ой! ret
определяется дважды. «Итак? Удалите вторую декларацию». ты говоришь. Но это делает код асимметричным, и вы получаете больше ограничений рефакторинга.
Конечно, я сам смешиваю объявления и код; нет причин относиться к этому догматично (иначе ваша карма может вытеснить вашу догму :-). Но вы должны знать, в чем заключаются сопутствующие проблемы.