C99 смешанные объявления и код в проектах с открытым исходным кодом?

Почему до сих пор C99 смешанные объявления и код не используется в проектах с открытым исходным кодом на C, как ядра Linux или гном?

Мне очень нравятся смешанные объявления и код, поскольку он делает код более читаемым и предотвращает появление ошибок, ограничивая область переменных максимально узкой. Это рекомендуется Google для C++.

например, Linux требует по крайней мере GCC 3.2 и GCC 3.1 поддержка для смешанных деклараций и кода C99

7 ответов


Это старый вопрос, но я собираюсь предположить, что инерция является причиной того, что большинство этих проектов все еще используют правила объявлений ANSI C.

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

  • переносимость. Многие проекты с открытым исходным кодом работают в предположении, что pedantic ANSI C является наиболее портативным способом написания программного обеспечения.

  • возраст. Многие из этих проектов предшествуют C99 spec и авторы могут предпочесть согласованный стиль кодирования.

  • невежество. Программисты, отправляющие до C99 и не знают о преимуществах смешанных деклараций и кода. (Альтернативная интерпретация: разработчики полностью осознают потенциальные компромиссы и решают, что смешанные декларации и заявления не стоят усилий. Я очень не согласен, но редко два программиста соглашаются на что-либо.)

  • FUD. Программисты вид смешанные объявления и код как "C++ism" и не любят его по этой причине.


вы не нужна смешанная декларация и код для ограничения области. Вы можете сделать:

{
  int c;
  c = 1;
  {
    int d = c + 1;
  }
}

в C89. Что касается того, почему эти проекты не использовали смешанные объявления (предполагая, что это правда), это, скорее всего, случай "если он не сломан, не исправляйте его."


есть мало причин переписывать ядро Linux для внесения косметических изменений, которые не обеспечивают повышения производительности.

Если база кода работает, то зачем менять ее по косметическим причинам?


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

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

OTOH, функция, которая должна смешивать переменные и код для чтения, вероятно, слишком велика. Это один из признаков (наряду со слишком вложенными блоками, встроенными комментариями и другими вещами), которые необходимы некоторым разделам функции абстрагироваться в отдельные функции (и объявляться static, поэтому оптимизатор может встроить их).

еще одна причина сохранять объявления в начале функций: если вам нужно изменить порядок выполнения операторов в коде, вы можете переместить переменную из своей области, не осознавая этого, так как область переменной, объявленной в середине кода, не очевидна в отступе (если вы не используете блок для отображения области). Это легко исправить, так что это просто раздражение, но новый код часто подвергается такого рода трансформации, и раздражение может быть кумулятивным.

и еще одна причина: у вас может возникнуть соблазн объявить переменную, чтобы взять код возврата ошибки из функции, например:

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 определен дважды. "Так? Удалите второе объявление.- ты говоришь. Но это делает код асимметричным, и вы в конечном итоге получаете больше рефакторинга ограничения.


может быть, это не нужно, может быть, разделение хорошо? Я делаю это на C++, который также имеет эту функцию.


нет причин изменять код таким образом, и C99 по-прежнему не поддерживается компиляторами. В основном речь идет о переносимости.


нет никакой пользы. Объявление всех переменных в начале функции (pascal like) гораздо более ясно, в C89 вы также можете объявить переменные в начале каждой области (пример внутренних циклов), что является практичным и кратким.