Tujuan dari rangkaian Trigraph dalam C ++?

127

Menurut C ++ '03 Standard 2.3 / 1:

Sebelum pemrosesan lain terjadi, setiap kemunculan salah satu dari tiga karakter berikut (“sekuens trigraph”) digantikan oleh karakter tunggal yang ditunjukkan pada Tabel 1.

----------------------------------------------------------------------------
| trigraph | replacement | trigraph | replacement | trigraph | replacement |
----------------------------------------------------------------------------
| ??=      | #           | ??(      | [           | ??<      | {           |
| ??/      | \           | ??)      | ]           | ??>      | }           |
| ??’      | ˆ           | ??!      | |           | ??-      | ˜           |
----------------------------------------------------------------------------

Dalam kehidupan nyata itu berarti bahwa kode printf( "What??!\n" );akan menghasilkan pencetakan What|karena ??!merupakan urutan trigraph yang diganti dengan |karakter.

Pertanyaan saya adalah apa tujuan menggunakan trigraph? Apakah ada manfaat praktis menggunakan trigraph?

UPD : Dalam jawaban disebutkan bahwa beberapa keyboard Eropa tidak memiliki semua karakter tanda baca, jadi programmer non-AS harus menggunakan trigraph dalam kehidupan sehari-hari?

UPD2 : Visual Studio 2010 memiliki dukungan trigraph dimatikan secara default.

Kirill V. Lyadvinsky
sumber
Beberapa tanda baca lebih sulit dijangkau pada keyboard Eropa (sampai-sampai beberapa programmer menggunakan tata letak AS untuk mengetik lebih cepat) Belum pernah melihat di mana tanda baca sama sekali hilang - mungkin untuk bahasa slavik?
peterchen
2
Mungkin saja beberapa terminal dan / atau virtualisasi tidak memungkinkan Anda mengakses beberapa karakter dengan mudah. Dalam pengalaman saya pelaku utama adalah tilde.
Francesco
1
mengetikkan ini pada keyboard DE-deadkeys saya, # adalah kunci di sebelah kembali, \ adalah "AltGr" + "ß" (di sebelah 0), ^ adalah "^" + "^" (karena deadkey; di sebelah 1) , [adalah "AltGr" + "8",] adalah "AltGr" + "9", | adalah "AltGr" + "<", {is "AltGr" + "7",} adalah "AltGr" + "0", dan ~ adalah "~" + "~" (karena deadkey, tepat di atas #). jadi bukan masalah besar. jari-jari saya seperti mengetik kombinasi ini sendiri :-D
nonchip
1
Saya pikir, itu normal untuk memiliki dua tata letak keyboard dan mengubahnya sesuai dengan pekerjaan yang saya lakukan di komputer. Ini cara umum di kawasan Eropa tengah. Cukup menyeramkan menggunakan trigraph ini. Saya akan memilih untuk menghapus ini dari standar.
VX
1
@VX Anda memiliki keinginan Anda!
graham.reeds

Jawaban:

97

Pertanyaan ini (tentang digraf yang terkait erat) memiliki jawabannya.

Itu bermuara pada kenyataan bahwa set karakter ISO 646 tidak memiliki semua karakter dari sintaks C, jadi ada beberapa sistem dengan keyboard dan tampilan yang tidak dapat berurusan dengan karakter (meskipun saya membayangkan bahwa ini sangat langka sekarang).

Secara umum, Anda tidak perlu menggunakannya, tetapi Anda perlu tahu tentang mereka untuk masalah yang Anda hadapi. Trigraph adalah alasan ?karakter ' ' memiliki urutan pelarian:

'\?'

Jadi beberapa cara Anda dapat menghindari masalah contoh Anda adalah:

 printf( "What?\?!\n" ); 

 printf( "What?" "?!\n" ); 

Tetapi Anda harus ingat ketika Anda mengetik keduanya '?' karakter yang Anda mungkin memulai trigraph (dan tentu saja tidak pernah sesuatu yang saya pikirkan).

Dalam praktiknya, trigraph dan digraf adalah sesuatu yang tidak saya khawatirkan sama sekali sehari-hari. Tetapi Anda harus mewaspadai mereka karena setiap dua tahun sekali Anda akan menemui bug yang terkait dengannya (dan Anda akan menghabiskan sisa hari itu dengan mengutuk keberadaan mereka). Akan lebih baik jika kompiler dapat dikonfigurasikan untuk memperingatkan (atau kesalahan) ketika menemukan trigraph atau digraf, jadi saya bisa tahu saya punya sesuatu yang harus saya tangani dengan sadar.

Dan hanya untuk kelengkapan, digraf jauh lebih berbahaya karena mereka diproses sebagai token, sehingga digraf di dalam string literal tidak akan ditafsirkan sebagai digraf.

Untuk pendidikan yang bagus tentang berbagai kesenangan dengan tanda baca dalam program C / C ++ (termasuk bug trigraph yang pasti akan membuat saya mencabut rambut saya), lihat artikel Herb Sutter's GOTW # 86 .


Tambahan:

Sepertinya GCC tidak akan memproses (dan akan memperingatkan tentang) trigraph secara default. Beberapa kompiler lain memiliki opsi untuk mematikan dukungan trigraph (misalnya IBM). Microsoft mulai mendukung peringatan (C4837) di VS2008 yang harus diaktifkan secara eksplisit (menggunakan -Dinding atau sesuatu).

Michael Burr
sumber
Kompatibilitas dengan C adalah satu-satunya alasan? Apakah mungkin bertemu dengan mereka di program C ++ modern?
Kirill V. Lyadvinsky
Ya, C ++ mendukung trigraph dan digraf juga.
Michael Burr
4
Seingat saya, setidaknya satu kompiler yang saya gunakan (g ++?) Memerlukan opsi baris perintah eksplisit sebelum trigraph dan atau digraph diterjemahkan, jika tidak, peringatan diberikan tetapi tidak ada substitusi.
KTC
1
@ Jla3ep - Saya pribadi tidak pernah memiliki kebutuhan untuk trigraph, tetapi sayangnya kompiler akan memproses kode dengan mereka, jadi Anda perlu menyadarinya (untuk menghindari penggunaan yang tidak disengaja). Juga, jika Anda mendapatkan kode dari tempat lain, Anda mungkin akan menggunakan sengaja, tetapi itu akan sangat luar biasa. Saya pikir saya telah mengalami trigraph yang sengaja digunakan sekali dalam 20+ tahun (itu adalah beberapa kode untuk mainframe IBM).
Michael Burr
1
Itu benar-benar hanya membuat saya gugup ketika trigraph diperluas dalam komentar untuk melakukan hal-hal yang mengejutkan.
Joshua
23

Anak-anak hari ini! :-)

Ya, peralatan asing, seperti terminal IBM 3270. 3270 memiliki, jika saya ingat, tidak ada kawat gigi keriting! Jika Anda ingin menulis C pada mini / mainframe IBM, Anda harus menggunakan trigraph celaka untuk setiap batas blok. Untungnya, saya hanya perlu menulis perangkat lunak dalam C untuk meniru beberapa fasilitas komputer mini IBM, tidak benar-benar menulis perangkat lunak C pada Sistem / 36.

Lihat di sebelah tombol "P":

papan ketik

Hmmm. Sulit dikatakan. Ada tombol tambahan di sebelah "carriage return", dan saya mungkin memilikinya mundur: mungkin itu pasangan "[" / "]" yang hilang. Bagaimanapun, keyboard ini akan membuat Anda sedih jika Anda harus menulis C.

Juga, terminal-terminal ini menampilkan EBCDIC, set karakter mainframe "asli" IBM, bukan ASCII (terima kasih, Pavel Minaev, untuk pengingatnya).

Di sisi lain, seperti panduan GNU C mengatakan: "Anda tidak perlu kerusakan otak ini." Kompiler gcc membiarkan "fitur" ini dinonaktifkan secara default.

Roboprog
sumber
1
Ada tombol reset di keyboard. Itu luar biasa! Aneh yang menarik perhatianku dulu.
l46kok
10
Siapa pun yang ingin menggunakan C ++ 17 pada mesin EBCDIC, harus dipenjara karena necrophilia.
SF.
Kecuali sebuah platform tidak memiliki karakter sama sekali selain dari yang ada di ISO646, tidak bisa semua yang dapat dilakukan dengan trigraph, dapat dilakukan dengan mengharuskan setiap implementasi menentukan backslash atau karakter apa pun yang tidak ada dalam karakter C yang ditetapkan sebagai "meta" karakter, ganti semua referensi ke backslash di Standar dengan "meta", dan menambahkan backslash / meta lolos untuk setiap anggota set karakter C yang tidak ada di ISO-646?
supercat
22

Dari The C++ Programming LanguageEdisi Khusus, halaman 829

Karakter ASCII khusus [, ], {, }, |, dan\ menduduki posisi set karakter ditunjuk sebagai abjad oleh ISO. Di sebagian besar rangkaian karakter ISO-646 nasional Eropa, posisi ini ditempati oleh huruf yang tidak ditemukan dalam alfabet Inggris.

Seperangkat trigraph disediakan untuk memungkinkan karakter nasional diekspresikan dalam cara yang portabel menggunakan set karakter minimal yang benar-benar standar. Ini bisa berguna untuk pertukaran program, tetapi itu tidak mempermudah orang untuk membaca program. Secara alami, solusi jangka panjang untuk masalah ini adalah untuk programmer C ++ mendapatkan peralatan yang mendukung bahasa ibu mereka dan C ++ dengan baik. Sayangnya, ini tampaknya tidak mungkin dilakukan oleh beberapa orang, dan pengenalan peralatan baru bisa menjadi proses yang sangat lambat.

rampok
sumber
7
"Pengenalan peralatan baru bisa menjadi proses yang sangat lambat". Terutama dibandingkan dengan proses cepat dan tanpa rasa sakit dari fitur bahasa pemrograman standar.
jforberg
4
Jika ini adalah kludge untuk tata letak keyboard, maka lucu bahwa tidak ada trigraph misalnya untuk mengetik `, yang hilang dari bahasa Italia dan beberapa tata letak keyboard lainnya
badp
15

Mereka digunakan pada sistem yang tidak memiliki beberapa karakter dalam rangkaian karakter dasar C ++. Tidak perlu dikatakan, sistem seperti itu sangat langka.

CB Bailey
sumber
2
Apakah itu berarti bahwa saya tidak akan pernah menggunakannya dalam kehidupan nyata?
Kirill V. Lyadvinsky
1
Tinggal di negara mana? Tidak semua keyboard untuk semua bahasa memiliki kunci yang diperlukan.
David Thornley
2
Ya, tetapi Anda mungkin perlu menyadari keberadaannya jika seseorang menyebabkan hasil yang tidak terduga ketika dimasukkan dalam, katakanlah, string literal.
CB Bailey
4
@ David Thornley: Sebagian besar sistem modern mendukung semua karakter dasar C ++ bahkan jika mereka tidak di tempat konvensional atau memerlukan urutan pengubah untuk mengetik. Trigraph hanya perlu dipelihara dalam kode sumber pada sistem di mana karakter sebenarnya tidak dapat diwakili dalam set karakter sistem. Saya masih berpendapat bahwa sistem seperti itu sangat jarang.
CB Bailey
9

Trigraph telah diusulkan untuk dihapus dalam C ++ 0x. Yang mengatakan, tampaknya masih ada argumen kuat dalam mendukung mereka - lihat kertas komite C ++ N2910 yang membahas hal ini. Tampaknya, EBCDIC adalah salah satu benteng utama di mana mereka dibutuhkan.

Pavel Minaev
sumber
Ya, "bahasa asing" itu! :-)
Roboprog
Mereka tidak banyak bicara kecuali "hasil dari survei internal umpan balik pelanggan", tapi ah. Saya terkejut bahwa EBCDIC masih digunakan secara luas (dan bahwa sistem ini mengharapkan untuk menggunakan kompiler C ++ 0x)
peterchen
5

Saya telah melihat trigraph yang digunakan pada awal 90-an untuk membantu mengkonversi program PL / 1 dari mainframe untuk dijalankan / dikompilasi / di-debug pada PC.

Mereka berkecimpung dengan mengedit PL / I pada PC menggunakan kompiler PL / I ke C dan mereka ingin kode untuk bekerja ketika dipindahkan kembali ke mainframe yang tidak mendukung kurung kurawal. Saya menyarankan agar mereka dapat menggunakan macro seperti

#def BEGIN {    
#def END }  

atau sebagai alternatif PL / I yang ramah

#def BEGIN ??<
#def END ??>

dan jika mereka benar-benar ingin mendapatkan kesenangan mereka bisa mencoba

#ifdef MAINFRAME
    #def BEGIN ??<
    #def END ??>
#else
    #def BEGIN {    
    #def END }  
#endif

dan kemudian program akan terlihat seperti ditulis dalam Pascal. Mereka hanya memandang saya lucu dan tidak akan berbicara kepada saya selama sisa hari itu. Saya tidak berpikir saya menyalahkan mereka. :)

Apa yang membunuh upaya apa yang bukan grafik-tri, itu adalah perbedaan sistem IO antara platform. Membuka file pada PC jauh berbeda dari mainframe yang akan memperkenalkan terlalu banyak kludges untuk membuat kode yang sama berjalan pada keduanya.

Kelly S. Prancis
sumber
PL / 1 = Versi C IBM (kurang lebih). Lihat komentar saya: terminal IBM tidak memiliki kunci '{' / '}' :-( Agak sulit untuk menulis C [++] pada salah satu dari ini, sebaliknya.
Roboprog
3

Terutama karena standar C memperkenalkan mereka kembali pada tahun 1989, ketika ada masalah dengan kehadiran karakter yang dipetakan trigraph pada beberapa mesin. Pada saat standar C ++ diterbitkan pada tahun 1998, kebutuhan akan trigraph tidak terlalu bagus. Mereka adalah kutil pada C; mereka hanya kutil pada C ++. Ada kebutuhan bagi mereka - terutama di luar dunia berbahasa Inggris - itulah sebabnya mereka ditambahkan ke C.

Jonathan Leffler
sumber
1
Saya selalu curiga bahwa IBM tidak berbicara bahasa Inggris :-)
Roboprog
3

Beberapa keyboard Eropa tidak (tidak?) Memiliki semua karakter tanda baca yang dimiliki keyboard AS, karena mereka memerlukan kunci untuk karakter alfabet yang tidak biasa. Jadi misalnya (mengada-ada), keyboard Swedia akan memiliki A-ring di mana kurung kurawal berada.

Untuk mengakomodasi para pengguna tersebut, trigraph adalah cara untuk memasukkan tanda baca menggunakan hanya karakter ASCII yang paling umum.

Ned Batchelder
sumber
4
Trigraphs sebenarnya bukan tentang entri data (mereka membuat kode sangat tidak dapat dibaca), mereka lebih tentang sistem yang sebenarnya tidak memiliki karakter yang diperlukan. Jika suatu sistem dapat merekam dan menampilkan karakter - bahkan jika trigraph seperti urutan kunci perlu diketik - akan jauh lebih mudah untuk tidak mempertahankan urutan trigraph dalam sumber.
CB Bailey
2

Mereka ada di sana sebagian besar karena alasan historis. Saat ini, sebagian besar papan ketik modern untuk sebagian besar bahasa memungkinkan akses ke semua karakter itu, tetapi ini pernah menjadi masalah pada beberapa papan ketik Eropa. Inilah mengapa trigraph ditemukan.

Jika Anda tidak tahu untuk apa itu, Anda tidak boleh menggunakannya.

Meskipun demikian, tetap baik untuk menyadarinya, karena Anda mungkin secara tidak sengaja dan tidak sengaja menggunakannya dalam kode Anda.

sbi
sumber