int a [] = {1,2,}; Koma aneh diizinkan. Ada alasan khusus?

335

Mungkin saya bukan dari planet ini, tetapi bagi saya tampaknya hal berikut ini adalah kesalahan sintaksis:

int a[] = {1,2,}; //extra comma in the end

Tapi ternyata tidak. Saya terkejut ketika kode ini dikompilasi pada Visual Studio, tapi saya telah belajar untuk tidak mempercayai MSVC compiler sejauh C ++ aturan yang bersangkutan, jadi aku memeriksa standar dan itu adalah diperbolehkan oleh standar juga. Anda dapat melihat 8.5.1 untuk aturan tata bahasa jika Anda tidak percaya kepada saya.

masukkan deskripsi gambar di sini

Kenapa ini diizinkan? Ini mungkin pertanyaan bodoh yang tidak berguna tapi saya ingin Anda mengerti mengapa saya bertanya. Jika itu adalah sub-kasus aturan tata bahasa umum, saya akan mengerti - mereka memutuskan untuk tidak membuat tata bahasa umum lebih sulit hanya untuk melarang koma yang berlebihan pada akhir daftar penginisialisasi. Tapi tidak, koma tambahan diizinkan secara eksplisit . Sebagai contoh, itu tidak diperbolehkan untuk memiliki koma yang berlebihan di akhir daftar argumen fungsi-panggilan (ketika fungsi mengambil ...), yang normal .

Jadi, sekali lagi, apakah ada alasan khusus koma yang berlebihan ini diizinkan secara eksplisit ?

Armen Tsirunyan
sumber
10
Setiap orang tampaknya setuju untuk 'kemudahan menambah baris baru' - tetapi apakah orang mendefinisikan spesifikasi bahasa benar-benar peduli tentang hal-hal seperti itu? Jika mereka benar-benar mengerti mengapa mereka tidak mengabaikan yang hilang ;ketika jelas token berikutnya sebenarnya adalah pernyataan berikutnya.
YetAnotherUser
35
@YetAnotherUser: Ya, perancang bahasa mempertimbangkan hal-hal seperti itu. Mengizinkan Anda untuk melepaskan titik koma akan memiliki dampak yang jauh lebih besar dan akan sangat ambigu di banyak bagian bahasa (ingat, spasi putih bukan semantik dalam bahasa C). Koma ekstra adalah bahwa kasus ini tidak ambigu. Titik koma ekstra hampir tidak pernah ambigu, dan juga diizinkan. Dalam kasus di mana ambigu (setelah for()contoh), menambahkannya melemparkan peringatan kompiler.
Rob Napier
5
@ Tomalak: Ini ambigu bagi pembaca manusia, dan seringkali merupakan kesalahan. Itu sebabnya ia memberi peringatan. Demikian pula if (x = 1)tidak ambigu dalam tata bahasa, tetapi sangat ambigu bagi manusia, dan dengan demikian melemparkan peringatan.
Rob Napier
12
@ Rob: ifContoh Anda juga tidak ambigu. Saya tidak berpikir "ambigu" berarti apa yang Anda pikirkan artinya!
Lightness Races in Orbit
5
Selama kami setuju bahwa itu adalah sesuatu yang berguna bagi kompiler untuk melindungi kami dari, sementara koma tertinggal dalam deklarasi array bukanlah sesuatu yang berguna bagi kompiler untuk melindungi kami dari.
Rob Napier

Jawaban:

436

Itu membuatnya lebih mudah untuk menghasilkan kode sumber, dan juga untuk menulis kode yang dapat dengan mudah diperpanjang di kemudian hari. Pertimbangkan apa yang diperlukan untuk menambahkan entri tambahan ke:

int a[] = {
   1,
   2,
   3
};

... Anda harus menambahkan koma ke baris yang ada dan menambahkan baris baru. Bandingkan dengan kasus di mana ketiganya sudah memiliki koma setelahnya, di mana Anda hanya perlu menambahkan baris. Demikian juga jika Anda ingin menghapus garis, Anda dapat melakukannya tanpa khawatir tentang apakah itu baris terakhir atau tidak, dan Anda dapat memesan ulang garis tanpa mengotak-atik koma. Pada dasarnya itu berarti ada keseragaman dalam cara Anda memperlakukan garis.

Sekarang pikirkan tentang menghasilkan kode. Sesuatu seperti (pseudo-code):

output("int a[] = {");
for (int i = 0; i < items.length; i++) {
    output("%s, ", items[i]);
}
output("};");

Tidak perlu khawatir tentang apakah item yang sedang Anda tulis adalah yang pertama atau yang terakhir. Jauh lebih sederhana.

Jon Skeet
sumber
89
Juga, ketika menggunakan VCS, "diff" antara dua versi lebih bersih karena hanya satu baris yang berubah ketika item ditambahkan atau dihapus.
Kevin Panko
47
@ Néstor: Mengapa "tidak beruntung"? Apa kerugiannya di sini? Hanya karena beberapa pertimbangan telah diberikan kepada pembuatan kode (dan manipulasi mudah) untuk satu bagian kecil bahasa tidak berarti itu harus menjadi motivasi utama di balik semua keputusan dalam bahasa. Ketik inferensi, penghapusan semi-titik dua dll memiliki implikasi besar untuk bahasa. Anda sedang membuat dikotomi palsu di sini, IMO.
Jon Skeet
18
@ Néstor: Itu di mana kemenangan pragmatisme lebih dogmatisme: mengapa hal itu harus sepenuhnya satu hal atau sepenuhnya yang lain, ketika itu lebih berguna untuk menjadi campuran keduanya? Bagaimana itu sebenarnya menghalangi, bisa menambahkan koma di akhir? Apakah ini sebuah inkonsistensi yang pernah menghalangi Anda dalam arti apa pun? Jika tidak, harap pertimbangkan ketidakseimbangan yang tidak relevan terhadap manfaat praktis dari membiarkan koma pada akhirnya.
Jon Skeet
8
@Mrchief: Ini bukan masalah tingkat pengetikan - ini masalah kesederhanaan, saat menyalin, menghapus, atau memesan kembali item. Itu membuat hidup saya lebih sederhana baru kemarin. Tanpa kekurangan, mengapa tidak membuat hidup lebih mudah? Sedangkan untuk mencoba mengarahkan jari ke MS, saya sangat curiga ini telah di C sejak sebelum Microsoft bahkan ada ... Anda mengatakan pembenaran ini tampak aneh, tapi saya yakin itu menguntungkan ribuan pengembang di ratusan perusahaan setiap hari. Bukankah itu penjelasan yang lebih baik daripada mencari sesuatu yang menguntungkan penulis kompiler?
Jon Skeet
6
Ini ada di K&R C.
Ferruccio
126

Ini berguna jika Anda melakukan sesuatu seperti ini:

int a[] = {
  1,
  2,
  3, //You can delete this line and it's still valid
};
Skilldrick
sumber
6
JavaScript mendukung sintaks ini:, var a = [1, 2,];demikian juga sebagian besar bahasa lain yang saya tahu ... ActionScript, Python, PHP.
Sean Fujiwara
14
@Sean Itu akan menyebabkan kesalahan parse di IE JavaScript, jadi berhati-hatilah!
Skilldrick
10
Itu tidak cocok untuk saya di IE9. Tapi itu memang melakukan sesuatu yang aneh ... itu menciptakan elemen nol. Saya akan berhati-hati.
Sean Fujiwara
5
@Sean Maaf, Anda benar - ini bukan kesalahan parse di IE, tetapi akan memasukkan elemen tambahan yang diatur ke undefined.
Skilldrick
3
Yang paling membuat frustrasi, JSON tidak mendukung sintaks ini.
Timmmm
38

Kemudahan penggunaan untuk pengembang, saya akan berpikir.

int a[] = {
            1,
            2,
            2,
            2,
            2,
            2, /*line I could comment out easily without having to remove the previous comma*/
          }

Selain itu, jika karena alasan apa pun Anda memiliki alat yang menghasilkan kode untuk Anda; alat tidak perlu peduli apakah itu item terakhir di inisialisasi atau tidak.

vcsjones
sumber
32

Saya selalu berasumsi akan membuatnya lebih mudah untuk menambahkan elemen tambahan:

int a[] = {
            5,
            6,
          };

hanya menjadi:

int a[] = { 
            5,
            6,
            7,
          };

di kemudian hari.

Oliver Charlesworth
sumber
3
Saya tidak berpikir membuat pengeditan sedikit lebih cepat adalah alasan yang baik untuk mengacaukan sintaks. IMHO ini hanyalah fitur C ++ aneh lainnya.
Giorgio
3
@Giorgio: Ya, ini diwarisi dari C. Sangat mungkin bahwa itu hanya kekhilafan dalam spesifikasi bahasa asli, yang kebetulan memiliki efek samping yang bermanfaat.
Oliver Charlesworth
Ok, saya tidak tahu bahwa itu berasal dari C. Saya hanya memeriksa bahwa itu diperbolehkan di Jawa juga. Rasanya agak aneh: dalam intuisi saya koma adalah pemisah bukan terminator. Selain itu, dimungkinkan untuk menghilangkan koma terakhir. Jadi, apakah itu terminator, separator, atau keduanya? Tapi OK, fitur ini tersedia dan bagus untuk diketahui.
Giorgio
11
@Iorgio - kode sumber untuk manusia, bukan mesin. Hal-hal kecil seperti ini untuk menjaga kita dari membuat kesalahan transposisi sederhana adalah berkah, bukan kekhilafan. Sebagai referensi, ia juga bekerja dengan cara ini dalam PHP dan ECMAScript (dan karenanya JavaScript dan ActionScript), meskipun tidak valid dalam notasi objek JavaScript (JSON) (mis. [1,2,3,]OK tapi {a:1, b:2, c:3,}tidak).
Dereleased
1
@Groky: Semakin saya memikirkannya, semakin saya yakin bahwa sintaksis bahasa pemrograman harus sesederhana dan konsisten mungkin dan dengan beberapa pengecualian mungkin: ini membuatnya lebih mudah untuk mempelajari bahasa (lebih sedikit aturan untuk diingat ). Keuntungan dari menyimpan satu atau dua penekanan tombol saat menambahkan / menghapus item ke / dari daftar (yang, omong-omong, saya tidak melakukan itu sering dibandingkan dengan jumlah total waktu saya menghabiskan pengkodean) tampaknya agak sepele bagi saya dibandingkan dengan memiliki sintaks yang jelas.
Giorgio
21

Segala sesuatu yang dikatakan semua orang tentang kemudahan menambah / menghapus / menghasilkan baris sudah benar, tetapi tempat sebenarnya sintaks ini bersinar adalah ketika menggabungkan file sumber menjadi satu. Bayangkan Anda memiliki array ini:

int ints[] = {
    3,
    9
};

Dan anggap Anda telah memeriksa kode ini ke dalam repositori.

Kemudian teman Anda mengeditnya, dan menambahkannya di akhir:

int ints[] = {
    3,
    9,
    12
};

Dan Anda secara bersamaan mengeditnya, menambahkan ke awal:

int ints[] = {
    1,
    3,
    9
};

Semantik operasi semacam ini (menambah awal, menambah akhir) harus sepenuhnya menggabungkan aman dan perangkat lunak versi Anda (mudah-mudahan git) harus dapat diotomatiskan. Sayangnya, ini bukan masalahnya karena versi Anda tidak memiliki koma setelah angka 9 dan versi teman Anda tidak. Padahal, jika versi asli memiliki 9 trailing, mereka akan otomatis.

Jadi, aturan praktis saya adalah: gunakan koma trailing jika daftar tersebut mencakup beberapa baris, jangan gunakan itu jika daftar berada pada satu baris.

amoss
sumber
15

Trailing koma saya percaya diperbolehkan untuk alasan kompatibilitas ke belakang. Ada banyak kode yang ada, terutama yang dibuat secara otomatis, yang menempatkan tanda koma. Itu membuatnya lebih mudah untuk menulis loop tanpa syarat khusus pada akhirnya. misalnya

for_each(my_inits.begin(), my_inits.end(),
[](const std::string& value) { std::cout << value << ",\n"; });

Sebenarnya tidak ada keuntungan bagi programmer.

PS Meskipun lebih mudah untuk membuat kode secara otomatis dengan cara ini, saya sebenarnya selalu berhati-hati untuk tidak menempatkan koma trailing, upaya minimal, keterbacaan ditingkatkan, dan itu lebih penting. Anda menulis kode sekali, Anda membacanya berkali-kali.

Gene Bushuyev
sumber
5
Saya sangat tidak setuju; [Ini adalah pendapat saya bahwa] ia telah menemukan jalannya ke banyak bahasa yang dibuat lama setelah C justru karena menguntungkan bagi programmer untuk dapat bergeser di sekitar isi array, berkomentar garis mau tak mau, dan sebagainya, tanpa harus khawatir tentang kesalahan sintaks yang disebabkan transposisi konyol. Apakah kita belum cukup stres?
Dereleased
12
@Dereleased - dengan logika yang sama, mengapa tidak mengekor (apapun) diizinkan, bagaimana int a = b + c +;atau if(a && b &&);akan lebih mudah untuk hanya menyalin dan menempelkan apa saja di akhir dan lebih mudah untuk menulis generator kode. Masalah ini sepele, dan subyektif, dalam kasus seperti itu selalu baik untuk melakukan yang terbaik untuk pembaca kode.
Gene Bushuyev
1
@Gene Bushuyev: Tepat! Saya sering memiliki ekspresi panjang dengan + atau &&, dengan operator di akhir baris dan, tentu saja, saya harus menghabiskan waktu ekstra ketika saya ingin menghapus operan terakhir dari ekspresi. Saya pikir sintaks koma ini benar-benar aneh!
Giorgio
2
@GeneBushuyev - Saya tidak setuju dengan itu. Walaupun memungkinkan membuntuti koma dalam array dan sejenisnya adalah fitur penghapus bug dan membuat hidup Anda lebih mudah sebagai programmer, saya murni demi keterbacaan mengambil langkah-langkah untuk menghapus pernyataan trailing AND (&&), plusses dan operator lain-lain dari conditional pernyataan. Itu hanya jelek, IMO.
Sune Rasmussen
2
Mengenai &&operator, kadang-kadang saya melakukan conditional seperti if (true \n && b1 \n && b2)sehingga saya dapat menambah dan menghapus garis yang saya butuhkan.
Christian Mann
12

Salah satu alasan ini diizinkan sejauh yang saya tahu adalah bahwa itu harus mudah untuk secara otomatis menghasilkan kode; Anda tidak memerlukan penanganan khusus untuk elemen terakhir.

Fredrik Pihl
sumber
11

Itu membuat generator kode yang mengeluarkan array atau enumerasi lebih mudah.

Membayangkan:

std::cout << "enum Items {\n";
for(Items::iterator i(items.begin()), j(items.end); i != j; ++i)
    std::cout << *i << ",\n";
std::cout << "};\n";

Yaitu, tidak perlu melakukan penanganan khusus pada item pertama atau terakhir untuk menghindari meludah koma tertinggal.

Jika pembuat kode ditulis dengan Python, misalnya, mudah untuk menghindari meludah koma trailing dengan menggunakan str.join()fungsi:

print("enum Items {")
print(",\n".join(items))
print("}")
Maxim Egorushkin
sumber
10

Saya terkejut setelah selama ini tidak ada yang mengutip Annotated C ++ Reference Manual ( ARM ), ia mengatakan yang berikut tentang [dcl.init] dengan penekanan pada saya:

Jelas ada terlalu banyak notasi untuk inisialisasi, tetapi masing-masing tampaknya melayani gaya penggunaan tertentu dengan baik. The = {initializer_list, opt} notasi diwarisi dari C dan berfungsi baik untuk inisialisasi struktur data dan array. [...]

meskipun tata bahasanya telah berevolusi sejak ARM ditulis, asalnya tetap.

dan kita bisa pergi ke alasan C99 untuk melihat mengapa ini diizinkan di C dan dikatakan:

K&R memungkinkan koma tertinggal di penginisialisasi di akhir daftar penginisialisasi. Standar telah mempertahankan sintaks ini, karena memberikan fleksibilitas dalam menambah atau menghapus anggota dari daftar penginisialisasi, dan menyederhanakan pembuatan mesin dari daftar tersebut.

Shafik Yaghmour
sumber
1
Suara positif untuk jawaban yang paling didukung oleh literatur, dan sumber sebenarnya dari fitur ini.
Marko
10

Saya melihat satu kasus penggunaan yang tidak disebutkan dalam jawaban lain, makro favorit kami:

int a [] = {
#ifdef A
    1, //this can be last if B and C is undefined
#endif
#ifdef B
    2,
#endif
#ifdef C
    3,
#endif
};

Menambahkan makro ke pegangan terakhir ,akan sangat menyakitkan. Dengan perubahan kecil dalam sintaks ini mudah untuk dikelola. Dan ini lebih penting daripada kode yang dihasilkan mesin karena biasanya lebih mudah untuk melakukannya di Turing langue daripada preprocesor yang sangat terbatas.

Yankes
sumber
7

Satu-satunya bahasa di mana itu - dalam praktek * - tidak diperbolehkan adalah Javascript, dan itu menyebabkan jumlah masalah yang tak terhitung. Misalnya, jika Anda menyalin & menempelkan baris dari tengah array, menempelnya di akhir, dan lupa menghapus koma maka situs Anda akan benar-benar rusak untuk pengunjung IE Anda.

* Secara teori diizinkan tetapi Internet Explorer tidak mengikuti standar dan memperlakukannya sebagai kesalahan

Thomas Bonini
sumber
"Array" JavaScript (yang hanya objek dengan properti panjang magis) agak tidak biasa: var x = [,,,]legal (kecuali dalam IE <9, tetapi spek itu mengatakan itu legal)
Peter C
Menurut spesifikasi ECMAScript, ini benar-benar valid; secara teori itu harus bekerja di browser apa pun yang mengimplementasikan JavaScript sesuai dengan spesifikasi tersebut, terutama bagian dari spesifikasi yang ditemukan di sini .
Dereleased
1
Sayangnya JavaScript adalah tentang membuat aplikasi untuk publik. Jadi tidak, itu tidak valid ketika ~ 50% pengguna akan mengalami masalah dalam menggunakan aplikasi Anda. Dan ya, jika saya bisa, saya akan melarang IE <9 - terlalu banyak waktu dihabiskan hanya untuk membuat kode yang bagus bekerja di sana ...
kgadek
@Dere: ya, saya mengatakan banyak dalam jawaban saya =)
Thomas Bonini
@Dereleased microsoft menciptakan spesifikasi dan perintahnya sendiri yang menurut orang lain setidaknya mentalitasnya berubah (terima kasih Tuhan)
Chris McGrath
7

Lebih mudah untuk mesin, yaitu parsing dan pembuatan kode. Ini juga lebih mudah bagi manusia, yaitu modifikasi, komentar, dan keanggunan visual melalui konsistensi.

Dengan asumsi C, apakah Anda akan menulis yang berikut ini?

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    puts("Line 1");
    puts("Line 2");
    puts("Line 3");

    return EXIT_SUCCESS
}

Tidak. Bukan hanya karena pernyataan akhir adalah kesalahan, tetapi juga karena itu tidak konsisten. Jadi mengapa melakukan hal yang sama pada koleksi? Bahkan dalam bahasa yang memungkinkan Anda menghilangkan tanda koma dan koma terakhir, komunitas biasanya tidak menyukainya. Komunitas Perl, misalnya, tampaknya tidak suka menghilangkan tanda titik koma, baris satu baris. Mereka menerapkannya pada koma juga.

Jangan hilangkan koma dalam koleksi multiline karena alasan yang sama Anda tidak menghilangkan koma untuk blok kode multiline. Maksud saya, Anda tidak akan melakukannya bahkan jika bahasa itu memungkinkan, bukan? Baik?

Louis
sumber
Ada bahasa (misalnya Pascal) yang memungkinkan. Yaitu Anda harus memilih antara; sebagai terminator (C) atau sebagai pemisah (Pascal). Sama untuk ','. Akan baik bagi saya jika ',' adalah terminator, tetapi kemudian {1, 2, 3} harus menjadi kesalahan sintaksis.
Giorgio
6

Alasannya sepele: kemudahan menambah / menghapus garis.

Bayangkan kode berikut:

int a[] = {
   1,
   2,
   //3, // - not needed any more
};

Sekarang, Anda dapat dengan mudah menambahkan / menghapus item ke daftar tanpa harus menambahkan / menghapus koma sesekali.

Berbeda dengan jawaban lain, saya tidak benar-benar berpikir bahwa kemudahan membuat daftar adalah alasan yang valid: setelah semua, itu sepele untuk kode untuk kasus-khusus baris terakhir (atau pertama). Generator kode ditulis satu kali dan digunakan berkali-kali.

Vlad
sumber
6

Ini memungkinkan setiap baris untuk mengikuti formulir yang sama. Pertama, ini memudahkan untuk menambahkan baris baru dan memiliki sistem kontrol versi melacak perubahan secara bermakna dan juga memungkinkan Anda untuk menganalisis kode dengan lebih mudah. Saya tidak bisa memikirkan alasan teknis.

Mark B
sumber
5

Ini diperbolehkan untuk melindungi dari kesalahan yang disebabkan oleh elemen yang bergerak dalam daftar panjang.

Misalnya, mari kita asumsikan kita memiliki kode yang terlihat seperti ini.

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Super User",
        "Server Fault"
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

Dan itu bagus, karena menunjukkan trilogi asli dari situs-situs Stack Exchange.

Stack Overflow
Super User
Server Fault

Tapi ada satu masalah dengan itu. Anda lihat, catatan kaki di situs web ini menunjukkan Kesalahan Server sebelum Pengguna Super. Lebih baik memperbaikinya sebelum ada yang tahu.

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Server Fault"
        "Super User",
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

Lagipula, memindahkan garis di sekitar tidak mungkin sulit, bukan?

Stack Overflow
Server FaultSuper User

Saya tahu, tidak ada situs web yang disebut "Pengguna Server FaultSuper", tetapi kompiler kami mengklaim itu ada. Sekarang, masalahnya adalah bahwa C memiliki fitur penggabungan string, yang memungkinkan Anda untuk menulis dua string yang dikutip ganda dan menggabungkannya dengan tidak menggunakan apa pun (masalah serupa juga dapat terjadi dengan bilangan bulat, seperti- tanda memiliki beberapa makna).

Sekarang bagaimana jika array asli memiliki koma yang tidak berguna di akhir? Yah, garis akan dipindahkan, tetapi bug seperti itu tidak akan terjadi. Sangat mudah untuk melewatkan sesuatu sekecil koma. Jika Anda ingat untuk meletakkan koma setelah setiap elemen array, bug seperti itu tidak bisa terjadi. Anda tidak ingin membuang empat jam untuk men-debug sesuatu, sampai Anda menemukan bahwa koma adalah penyebab masalah Anda .

Konrad Borowski
sumber
4

Seperti banyak hal, koma jejak dalam penginisialisasi array adalah salah satu hal yang diwarisi oleh C ++ dari C (dan harus didukung selamanya). Pandangan yang sama sekali berbeda dari yang ditempatkan di sini disebutkan dalam buku "Rahasia C mendalam" .

Setelah itu ada contoh dengan lebih dari satu "koma paradoks":

char *available_resources[] = {
"color monitor"           ,
"big disk"                ,
"Cray"                      /* whoa! no comma! */
"on-line drawing routines",
"mouse"                   ,
"keyboard"                ,
"power cables"            , /* and what's this extra comma? */
};

kita membaca :

... bahwa trailing koma setelah initializer akhir tidak salah ketik, tapi blip dalam sintaks dibawa dari aborigin C . Ada atau tidaknya diizinkan tetapi tidak memiliki signifikansi . Pembenaran yang diklaim dalam alasan ANSI C adalah bahwa hal itu membuat generasi otomatis C lebih mudah. Klaim akan lebih kredibel jika koma tertinggal diizinkan di setiap daftar berperingkat koma , seperti dalam deklarasi enum, atau beberapa deklarator variabel dalam satu deklarasi. Mereka tidak.

... bagi saya ini lebih masuk akal

Nikos Athanasiou
sumber
2
Larangan terhadap koma dalam enumkasus ini agak menarik, karena itulah kasus di mana koma yang hilang akan menimbulkan ambiguitas paling sedikit. Diberikan struct foo arr[] = {{1,2,3,4,5}, {3,4,5,6,7}, }; ada dua arti yang masuk akal yang dapat diberikan oleh bahasa: buat array dua elemen, atau buat array tiga elemen di mana item terakhir memiliki nilai default. Jika C mengadopsi interpretasi yang kemudian, saya bisa melihat melarang enum foo {moe, larry, curly, };pada prinsip bahwa seharusnya hanya ada satu cara untuk menulis pernyataan (tanpa koma), tapi ...
supercat
1
... mengingat bahwa C bersedia mengabaikan koma dalam kasus di mana ia dapat secara wajar (tetapi tidak) diberi makna yang signifikan (yang akan menjadi argumen yang kuat untuk melarangnya di sana) itu aneh bahwa itu bukan tidak bersedia dalam kasus di mana koma tidak dapat memiliki makna [bahkan jika seseorang ditafsirkan enum foo {moe,,larry,curly,};sebagai melewatkan angka di antara moedan larry, umumnya tidak masalah apakah koma tertinggal diproses atau diabaikan. Satu-satunya kasus di mana itu bisa menjadi masalah adalah jika item terakhir adalah nilai maksimum untuk jenis yang dinyatakan, dan itu ...
supercat
1
... dapat ditangani dengan hanya mengatakan bahwa luapan yang terjadi setelah nilai enumerasi yang ditugaskan terakhir harus diabaikan.
supercat
@supercat Ada bahasa, seperti C #, di mana penelitian desain apriori mempertimbangkan fitur IDE dan integrasi ketika mendevolusikan bahasa. C bukan (dan tidak mungkin) salah satu dari bahasa-bahasa ini.
Nikos Athanasiou
Bahkan dengan bahasa seperti C #, mengubah tujuan desain telah menghasilkan beberapa ketidakkonsistenan desain yang cukup parah. Sebagai contoh, bahasa menahan diri dari mendukung segala bentuk over-jenis kembali untuk metode normal dan operator (meskipun kerangka kerja yang mendasarinya dapat mendukungnya) karena dianggap bertentangan dengan tujuan memiliki bahasa yang mudah dikompilasi, tetapi evaluasi lambda termasuk aturan inferensi tipe yang resolusinya NP-lengkap. Menambahkan metode baru / aturan operator yang berlebihan mungkin merusak kode yang ada (meskipun saya pikir aturan yang baik dapat meminimalkan bahaya seperti itu) ...
supercat
2

Selain pembuatan kode dan kemudahan pengeditan, jika Anda ingin mengimplementasikan parser, jenis tata bahasa ini lebih sederhana dan lebih mudah diimplementasikan. C # mengikuti aturan ini di beberapa tempat yang ada daftar item yang dipisahkan koma, seperti item dalam enumdefinisi.

Iravanchi
sumber
1

Itu membuat menghasilkan kode lebih mudah karena Anda hanya perlu menambahkan satu baris dan tidak perlu memperlakukan menambahkan entri terakhir seolah-olah itu kasus khusus. Ini terutama benar ketika menggunakan makro untuk menghasilkan kode. Ada dorongan untuk mencoba menghilangkan kebutuhan makro dari bahasa tersebut, tetapi banyak bahasa yang berkembang seiring dengan makro tersedia. Koma ekstra memungkinkan makro seperti yang berikut ini untuk didefinisikan dan digunakan:

#define LIST_BEGIN int a[] = {
#define LIST_ENTRY(x) x,
#define LIST_END };

Pemakaian:

LIST_BEGIN
   LIST_ENTRY(1)
   LIST_ENTRY(2)
LIST_END

Itu contoh yang sangat sederhana, tetapi sering pola ini digunakan oleh makro untuk mendefinisikan hal-hal seperti pengiriman, pesan, acara atau peta dan tabel terjemahan. Jika koma tidak diizinkan di akhir, kami akan membutuhkan spesial:

#define LIST_LAST_ENTRY(x) x

dan itu akan sangat canggung untuk digunakan.

Scott Langham
sumber
0

Sehingga ketika dua orang menambahkan item baru dalam daftar di cabang terpisah, Git dapat menggabungkan perubahan dengan benar, karena Git bekerja berdasarkan garis.

noɥʇʎԀʎzɐɹƆ
sumber
-4

Jika Anda menggunakan array tanpa panjang yang ditentukan, VC ++ 6.0 dapat secara otomatis mengidentifikasi panjangnya, jadi jika Anda menggunakan "int a [] = {1,2,};" panjang a adalah 3, tetapi yang terakhir tidak memiliki t diinisialisasi, Anda dapat menggunakan "cout <

zhi_jian
sumber
Apakah ini bug untuk VC6 yang tidak sesuai dengan standar?
Thomson