Powód umieszczenia typu funkcji i nazwy metody w różnych wierszach w C.

16

Właśnie zacząłem w firmie i jednym z komentarzy do stylu podczas mojej pierwszej recenzji kodu było to, że typ zwracanej nazwy i nazwa metody powinny być w różnych wierszach. Na przykład to

void foo() {
}

powinno być to

void
foo() {
}

Zawsze używałem pierwszego stylu i zastanawiałem się, czy istnieje jakiś inny powód niż osobiste preferencje, dlaczego ludzie używają drugiego stylu? Nie sądzę, żeby pierwszy w ogóle w ogóle szkodził czytelności. Czy jedno jest bardziej powszechne niż inne w przypadku programistów C i dużych projektów open source?

gsingh2011
źródło
3
Jest to w standardzie GNU (niekoniecznie mówiąc, że to dobrze, styl wzmacniający jest dziwny). gnu.org/prep/standards/standards.html#Formatting
Gauthier

Odpowiedzi:

19

zastanawiał się, czy istnieje jakiś inny powód niż osobiste preferencje, dlaczego ludzie używają drugiego stylu?

Jest to styl, który był popularny na początku C, więc może być tak, że robili to od bardzo dawna, mają dużo kodu, który wygląda tak i właśnie to wszyscy są do tego przyzwyczajeni. Nie tyle osobiste preferencje, co dynamika korporacyjna.

Innym powodem jest to, że nazwy funkcji zawsze zaczynają się w pierwszej kolumnie. Typy zwrotów różnią się długością i mogą być nieco skomplikowane - umieszczenie typu w osobnej linii ułatwia znalezienie nazwy funkcji.

Jeśli firma ma ustalony styl, może również mieć dokument standardów kodowania. Poproś o to. Może to wyjaśniać powody tego wyboru, a posiadanie kopii pomoże uniknąć podobnych problemów w przyszłych recenzjach.

Caleb
źródło
2
Wydaje mi się, że ma to również związek z limitem 80 znaków, który jest nadal używany i broniony przez wielu programistów. Jeśli chcesz mieć limit 80 znaków i chcesz używać opisowych nazw metod / funkcji, musisz pójść na kompromis. Podział nagłówka metody jest jednym z nich.
Sulthan
Deklaracja może być również dłuższa - pomyśl o różnych (niestandardowych) modyfikatorach, takich jak identyfikatory konwencji wywoływania (stdcall itp.), Informacje o widoczności symboli (DLLEXPORT) lub __attributes. A potem, patrząc również na C ++, możesz mieć stosunkowo złożone typy zwrotów, więc gdzieś trzeba dodać podział wiersza.
johannes,
@Sulthan To nie tylko programiści (którzy są przyzwyczajeni do okien terminali i używają edytorów terminali), co ciekawe. W składzie 72-80 znaków jest ogólnie uważane za idealną szerokość kolumny tekstu pod względem czytelności. (Dlatego też TeX i jego pochodne domyślnie przyjmują to, co niektórzy uważają za dziwnie wąskie kolumny.)
JAB
1
@JAB Właściwie to teraz. Wiem również, że czytanie uzasadnionego tekstu i czytanie kodu źródłowego to dwie bardzo różne rzeczy i nie mają prawie nic wspólnego, dlatego idealna szerokość jest nieistotna.
Sulthan
1
„Innym powodem jest to, że nazwy funkcji zawsze zaczynają się w pierwszej kolumnie [i tak są] łatwiejsze do znalezienia.” A to znacznie więcej niż tylko wizualna korzyść: teraz możemy wyszukać wyrażenie regularne ^start_of_a_long_funci od razu przejść do szukanej funkcji.
underscore_d
7

Jest to właściwie jedyna reguła formatowania kodu, którą znalazłem, ma zauważalny wpływ na czytelność i nie wymaga prawie żadnego wysiłku (zakładając, że Twój edytor kodu nie rozpocznie z tobą walki).

Dobrze jest zaprojektować język programowania, aby nazwy pojawiały się w spójnej pozycji w deklaracjach / definicjach. Uzasadnienie jest proste: masz ładną wizualną kotwicę (kręcone nawiasy klamrowe lub po prostu wiszące wcięcie), za pomocą której możesz od razu znaleźć początek nazwy. Nie musisz analizować języka podczas skanowania pliku, znajdź nazwę.

To tak samo, jak podczas formatowania dokumentu: kiedy zaczynasz nową sekcję, umieszczasz nazwę pogrubioną czcionką - często w osobnej linii - nie zakopaną gdzieś, niezróżnicowaną, długim zdaniem.

Wczesne C miało bardzo krótkie podpisy: typy zwracane były opcjonalne, a typy argumentów deklarowane po podpisie. Nazwy również były bardzo krótkie. Zmniejszyło to wpływ okazjonalnego typu powrotu kompensującego nazwę.

double dot(x, y);

Nadal jest lekkostrawny.

C ++ pogorszyło to nieco. Przenosi specyfikacje typów argumentów do podpisów, dzięki czemu podpisy są dłuższe. Ta składnia została później przyjęta podczas standaryzacji C.

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

jest mniej strawny, ale nie jest tak źle. (Fragment z Git)

Teraz rozważ współczesne praktyki programowania z długimi, opisowymi nazwami i sparametryzowanymi typami i zobacz, jak ten wybór stał się katastrofalny. Przykład z nagłówka 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(); 
}

Jeśli piszesz kod ogólny, takie podpisy nie są niczym niezwykłym. Możesz znaleźć przykłady o wiele gorszych przypadków, bez zbytniego wysiłku.

C, C ++ i ich pochodne, Java i C #, wydają się być wyjątkami od posiadania czytelnych deklaracji / definicji. Ich popularni poprzednicy i rówieśnicy (Fortran, ALGOL, Pascal) umieścili nazwy przed typami wyników i, na szczęście, wielu ich następców (Go, Scala, TypeScript i Swift, aby wymienić tylko kilka) wybrało również bardziej czytelne składnie.

użytkownik2313838
źródło
1
Ciesz się, że nie musisz pisać programów Fortran. Mówię wam, osobne zadeklarowanie argumentów funkcji dość szybko zadziała na nerwy, gdy będziecie zmuszeni to zrobić. Zwłaszcza, gdy próbuje się odczytać podpis funkcji, aby zrozumieć, jakich argumentów się spodziewa: C ++ ustawia typy dokładnie tam, gdzie należą, Fortran zmusza cię do wizualnego wyszukiwania słowa kluczowego dla nazwy zmiennej w celu ustalenia jej typu.
cmaster
2
Czy umieszczanie typów w deklaracji funkcji naprawdę zostało wynalezione przez C ++? Nigdy o tym nie słyszałem i staram się znaleźć cytaty.
underscore_d
1
Zobacz na rozwój języka C . W sekcji Normalizacja Ritchie wspomina, że ​​składnia została zapożyczona z C ++.
user2313838,
5

Pierwszy raz poznałem ten styl około 19 lat, pracując z C & C ++. Zaskoczyło mnie, jak ktoś mógł wymyślić tę złą rzecz.

Jedynym (potencjalnie) pozytywnym punktem, jaki mogłem znaleźć, jest to, że można znaleźć definicję funcitonu za pomocą grep ^ FuncName. Może być istotny czynnik ponad dekadę temu w niektórych prawdziwych społecznościach nienawidzących narzędzi ... W miejscu, w którym widziałem, zastosowano go do C ++ i funkcji członków klasy, które zabijają nawet ten atrybut.

Zgadnij moją opinię. :)

Balog Pal
źródło
1
grep -P '^(\w+::)?FuncName'
Kyle Strand
Tak, typy klas w nazwach funkcji wcale nie utrudniają korzystania z tego. Jest to więc nadal przydatna rzecz do szybkiego przeglądania plików źródłowych. Co do tego, że wygląda źle lub cokolwiek, opinie są opiniami: zacząłem myśleć, że wygląda lepiej.
underscore_d