Причина размещения типа функции и имени метода на разных строках в C


16

Я только начинал в компании, и один из стилевых комментариев в моем первом обзоре кода заключался в том, что тип возвращаемого значения и имя метода должны быть в разных строках. Например, это

void foo() {
}

должно быть это

void
foo() {
}

Я всегда использовал первый стиль, и мне было интересно, есть ли другие причины, кроме личных предпочтений, почему люди используют второй стиль? Я не думаю, что первое вообще ухудшает читабельность. Является ли один более распространенным, чем другой, программистами C и большими проектами с открытым исходным кодом?


3
Это в стандарте GNU (не обязательно говорить, что это хорошо, стиль поддержки странный). gnu.org/prep/standards/standards.html#Formatting
Готье,

Ответы:


19

Интересно, есть ли какая-либо причина, кроме личных предпочтений, почему люди используют второй стиль?

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

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

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


2
Я предполагаю, что это также связано с линией в 80 символов, которая все еще используется и защищается многими программистами. Если вы хотите иметь ограничение в 80 символов и хотите использовать описательные имена методов / функций, вы должны пойти на некоторые компромиссы. Разделение заголовка метода является одним из них.
Sulthan

Объявление также может быть длиннее - подумайте о различных (нестандартных) модификаторах, таких как идентификаторы соглашения о вызовах (stdcall и т. Д.), Информация о видимости символов (DLLEXPORT) или __attributes. И затем, когда вы смотрите на C ++, вы можете иметь относительно сложные возвращаемые типы, поэтому где-то, возможно, придется добавить разрыв строки.
Йоханнес

@ Sulthan Интересно, это не просто программисты (которые привыкли к оконным окнам и используют редакторы терминалов). При наборе текста 72-80 символов обычно считаются идеальной шириной для столбца текста с точки зрения читабельности. (Следовательно, почему TeX и его производные по умолчанию используют то, что некоторые люди считают странно узкими столбцами.)
JAB

1
@JAB Я на самом деле сейчас это. Я также знаю, что чтение оправданного текста и чтение исходного кода - это две совершенно разные вещи, которые почти не имеют ничего общего, поэтому идеальная ширина не имеет значения.
Sulthan

1
«Другая причина в том, что имена функций всегда начинаются с первого столбца, и поэтому их легче найти». И это гораздо больше, чем просто визуальное преимущество: теперь мы можем найти регулярное выражение ^start_of_a_long_funcи сразу перейти к функции, которую мы ищем.
underscore_d

7

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

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

Это то же самое, что и при форматировании документа: когда вы начинаете новый раздел, вы помещаете имя впереди жирным шрифтом - часто в отдельной строке - где-то не похороненным, недифференцированным, в длинном предложении.

Ранняя версия Си имела очень краткие подписи: типы возвращаемых данных были необязательными, а типы аргументов были объявлены после подписи. Имена также, как правило, были очень короткими. Это уменьшило влияние случайного типа возврата, компенсирующего имя.

double dot(x, y);

Все еще довольно легко усваивается.

C ++ сделал это немного хуже. Он перемещал спецификации типов аргументов в сигнатуры, делая подписи длиннее. Этот синтаксис был позже принят во время стандартизации C.

static struct origin *find_origin(struct scoreboard *sb,
                  struct commit *parent,
                  struct origin *origin)

менее усваивается, но не так уж плохо. (Выдержка из Git)

Теперь рассмотрим современные практики программирования с длинными описательными именами и параметризованными типами и посмотрим, как этот выбор стал катастрофическим. Пример из заголовка Boost:

template <class A1, class A2, class A3, class A4, class A5, class A6>
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&)
{ 
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
   return result_type(); 
}

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

C, C ++ и их производные, Java и C #, кажутся исключениями из наличия читаемых объявлений / определений. Их популярные предшественники и коллеги (Fortran, ALGOL, Pascal) помещали имена перед типами результатов, и, к счастью, многие из их преемников (Go, Scala, TypeScript и Swift и многие другие) также выбрали более читаемые синтаксисы.


1
Будьте благодарны, что вам не нужно писать программы на Фортране. Я говорю вам, что отдельное объявление аргументов вашей функции довольно быстро начнет действовать вам на нервы, как только вы будете вынуждены это сделать. Особенно при попытке прочитать сигнатуру функции, чтобы понять, какие аргументы она ожидает: C ++ помещает типы туда, где они принадлежат, Fortran заставляет вас начать визуальный поиск ключевого слова по имени переменной, чтобы определить ее тип.
cmaster - восстановить монику

2
Действительно ли помещение типов в объявление функции было придумано C ++? Я никогда не слышал об этом, и изо всех сил пытаюсь найти цитаты.
underscore_d

1
См . Развитие языка Си . В разделе «Стандартизация» Ритчи упоминает, что синтаксис был заимствован из C ++.
user2313838

5

Впервые я познакомился с этим стилем примерно на 19-м году, работая с C & C ++. Был в значительной степени озадачен тем, как кто-то может изобрести эту злую вещь.

Единственный (потенциально) положительный момент, который я смог найти, это то, что вы можете найти определение функции, используя grep ^ FuncName. Может быть значимым фактором десятилетие назад в некоторых реальных сообществах, ненавидящих инструменты ... В том месте, где я видел, оно применялось к функциям C ++ и членов класса, которые убивают даже этот атрибут.

Угадай мое мнение :)


1
grep -P '^(\w+::)?FuncName'
Кайл Стрэнд,

Да, типы классов в именах функций совсем не мешают использовать это. Так что это все еще полезная вещь для быстрой навигации по исходным файлам. Что касается того, что выглядит злым или что-то в этом роде, мнения - это мнения: я пришел к выводу, что это выглядит лучше.
underscore_d
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.