Alasan untuk menempatkan jenis fungsi dan nama metode pada baris yang berbeda di C

16

Saya baru saja mulai di sebuah perusahaan dan salah satu komentar gaya di review kode pertama saya adalah bahwa jenis kembali dan nama metode harus pada baris yang berbeda. Sebagai contoh, ini

void foo() {
}

seharusnya ini

void
foo() {
}

Saya selalu menggunakan gaya pertama, dan saya bertanya-tanya apakah ada alasan selain preferensi pribadi mengapa orang menggunakan gaya kedua? Saya tidak berpikir yang pertama menyakitkan keterbacaan sama sekali. Apakah satu lebih umum daripada yang lain dengan programmer C dan proyek open source besar?

gsingh2011
sumber
3
Ini dalam standar GNU (tidak harus mengatakan itu adalah hal yang baik, gaya bracing aneh). gnu.org/prep/standards/standards.html#Formatting
Gauthier

Jawaban:

19

bertanya-tanya apakah ada alasan selain preferensi pribadi mengapa orang menggunakan gaya kedua?

Itu adalah gaya yang populer pada masa-masa awal C, jadi alasannya mungkin karena itulah yang telah mereka lakukan untuk waktu yang sangat lama, mereka punya banyak kode yang terlihat seperti itu, dan itulah yang semua orang terbiasa. Preferensi pribadi tidak begitu banyak seperti momentum perusahaan.

Alasan lain adalah bahwa nama fungsi selalu dimulai di kolom pertama. Jenis kembali bervariasi panjangnya dan bisa agak rumit - menempatkan tipe pada barisnya sendiri membuat nama fungsi lebih mudah ditemukan.

Jika perusahaan memiliki gaya yang ditetapkan, mereka mungkin juga memiliki dokumen standar pengkodean. Minta itu. Ini dapat menjelaskan alasan pilihan ini, dan memiliki salinan akan membantu Anda menghindari masalah serupa di ulasan mendatang.

Caleb
sumber
2
Saya kira itu juga terhubung ke batas garis 80 karakter yang masih digunakan dan dipertahankan oleh banyak programmer. Jika Anda ingin memiliki batas 80 karakter dan Anda ingin menggunakan metode deskriptif / nama fungsi, Anda harus membuat beberapa kompromi. Membagi header metode adalah salah satunya.
Sulthan
Deklarasi juga bisa lebih lama - pikirkan tentang pengubah (non-standar) yang berbeda, seperti pemanggil pengenal konvensi (stdcall, dll.), Informasi tentang visibilitas simbol (DLLEXPORT) atau __attributes. Dan kemudian ketika juga melihat C ++ Anda dapat memiliki tipe pengembalian yang relatif kompleks sehingga di suatu tempat orang mungkin harus menambahkan jeda baris.
johannes
@Sulthan Bukan hanya programmer (yang digunakan untuk terminal windows dan menggunakan editor terminal), yang menarik. Dalam penyusunan huruf, 72-80 karakter umumnya dianggap sebagai lebar ideal untuk kolom teks dalam hal keterbacaan. (Oleh karena itu mengapa TeX dan turunannya default ke apa yang beberapa orang anggap kolom sempit aneh.)
JAB
1
@ JAB saya sebenarnya sekarang. Saya juga tahu bahwa membaca teks yang dibenarkan dan membaca kode sumber adalah dua hal yang sangat berbeda dan hampir tidak memiliki kesamaan sehingga lebar ideal tidak relevan.
Sulthan
1
"Alasan lain adalah bahwa nama fungsi selalu dimulai di kolom pertama [dan begitu juga] lebih mudah ditemukan." Dan ini jauh lebih dari sekadar manfaat visual: Sekarang kita dapat mencari regex ^start_of_a_long_funcdan segera dibawa ke fungsi yang kita cari.
underscore_d
7

Ini cukup banyak satu-satunya aturan pemformatan kode yang saya temukan benar-benar membuat dampak nyata pada keterbacaan dan hampir tidak ada upaya (dengan asumsi editor kode Anda tidak memulai pertengkaran dengan Anda karenanya).

Ini adalah desain bahasa pemrograman yang bagus untuk membuat nama muncul dalam posisi yang konsisten dalam deklarasi / definisi. Alasannya sederhana: Anda memiliki jangkar visual yang bagus (kurung kurawal atau hanya lekukan gantung) yang dapat Anda gunakan untuk segera menemukan awal nama. Anda tidak harus benar-benar menguraikan bahasa saat memindai melalui file menemukan nama.

Itu sama seperti ketika Anda memformat dokumen: ketika Anda memulai bagian baru Anda meletakkan nama di depan dalam huruf tebal - sering pada barisnya sendiri - tidak dikubur di suatu tempat, tidak berbeda, dalam kalimat yang panjang.

Awal C memiliki tanda tangan yang sangat singkat: tipe pengembalian adalah opsional dan tipe argumen dinyatakan setelah tanda tangan. Nama-nama juga cenderung sangat pendek. Ini mengurangi dampak dari memiliki tipe pengembalian sesekali mengimbangi nama.

double dot(x, y);

Masih cukup mudah dicerna.

C ++ membuat ini sedikit lebih buruk. Ini memindahkan spesifikasi tipe argumen menjadi tanda tangan yang membuat tanda tangan lebih lama. Sintaks ini kemudian diadopsi selama standarisasi C.

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

kurang mudah dicerna, tetapi tidak terlalu buruk. (Kutipan dari Git)

Sekarang pertimbangkan praktik pemrograman modern dengan nama deskriptif yang panjang dan tipe parametrized dan lihat bagaimana pilihan ini menjadi bencana. Contoh dari tajuk 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(); 
}

Jika Anda menulis kode generik, tanda tangan seperti itu bahkan tidak luar biasa. Anda dapat menemukan contoh kasus yang jauh lebih buruk daripada ini tanpa berusaha terlalu keras.

C, C ++, dan turunannya, Java dan C #, tampaknya menjadi pengecualian untuk memiliki deklarasi / definisi yang dapat dibaca. Pendahulu dan rekan-rekan mereka yang populer (Fortran, ALGOL, Pascal) menempatkan nama di depan tipe hasil dan, untungnya, banyak penerus mereka (Go, Scala, TypeScript, dan Swift untuk menyebutkan beberapa) telah memilih sintaksis yang lebih mudah dibaca juga.

pengguna2313838
sumber
1
Bersyukurlah bahwa Anda tidak harus menulis program Fortran. Saya katakan, secara terpisah mendeklarasikan argumen fungsi Anda akan membuat Anda cepat gugup begitu Anda dipaksa untuk melakukannya. Terutama ketika mencoba membaca tanda tangan fungsi untuk memahami argumen apa yang diharapkannya: C ++ menempatkan jenis tepat di tempat mereka berada, Fortran memaksa Anda untuk memulai pencarian kata kunci visual untuk nama variabel untuk menentukan jenisnya.
cmaster - mengembalikan monica
2
Apakah menempatkan jenis dalam deklarasi fungsi benar-benar ditemukan oleh C ++? Saya belum pernah mendengar hal itu, dan saya berjuang untuk menemukan kutipan.
underscore_d
1
Lihat Perkembangan Bahasa C . Di bagian Standardisasi Ritchie menyebutkan sintaksisnya dipinjam dari C ++.
user2313838
5

Saya pertama kali bertemu gaya ini pada seperti tahun 19 bekerja dengan C & C ++. Cukup bingung tentang bagaimana seseorang bisa menciptakan benda jahat ini.

Satu-satunya titik (berpotensi) positif yang bisa saya temukan adalah bahwa Anda dapat menemukan definisi funciton menggunakan grep ^ FuncName. Mungkin menjadi faktor yang relevan dekade + yang lalu di beberapa alat yang benar-benar membenci komunitas ... Di tempat saya melihatnya diterapkan ke C ++ dan fungsi anggota kelas, yang membunuh bahkan atribut ini.

Tebak pendapat saya. :)

Balog Pal
sumber
1
grep -P '^(\w+::)?FuncName'
Kyle Strand
Ya, tipe kelas dalam nama fungsi tidak menghalangi penggunaan ini sama sekali. Jadi, ini masih merupakan hal yang berguna untuk menavigasi file sumber dengan cepat. Adapun itu terlihat jahat atau apa pun, pendapat adalah opini: Saya pikir itu terlihat lebih baik.
underscore_d