Sabotase standar pengkodean [ditutup]

35

Ada berbagai standar pengkodean yang diberlakukan pada perusahaan perangkat lunak yang memiliki tujuan meningkatkan keandalan kode, portabilitas, dan, yang paling penting, keterbacaan dalam kode yang ditulis bersama oleh pengembang yang berbeda.

Dua contoh penting adalah MISRA C , dan standar C ++ yang dikembangkan untuk proyek JSF .

Ini biasanya dalam bentuk berikut, setelah dengan hati-hati menentukan arti kata "harus", "akan", "harus", "mungkin", dll.

Contoh:

Aturan 50: Variabel titik apung tidak boleh diuji untuk persamaan atau ketidaksetaraan yang tepat.

Dasar Pemikiran: Karena angka floating point dikenakan kesalahan pembulatan dan pemotongan, kesetaraan yang tepat mungkin tidak tercapai, bahkan ketika diharapkan.

Standar pengkodean ini menimbulkan batasan, biasanya pada kode yang legal dari sudut pandang kompiler, tetapi berbahaya atau tidak dapat dibaca, dan karenanya "dianggap berbahaya".

Sekarang mari kita penyalahgunaan ini!

Anda diterima sebagai anggota komite standardisasi kecil di perusahaan Anda, yang dimaksudkan untuk merancang standar pengkodean baru yang harus digunakan oleh setiap pengembang di perusahaan. Tanpa diketahui orang lain, Anda diam-diam mempekerjakan organisasi jahat dan memiliki misi untuk menyabot perusahaan. Anda harus mengusulkan satu atau lebih entri ke standar pengkodean yang nantinya akan menghambat pengembang. Namun, Anda harus berhati-hati untuk tidak membuat ini segera jelas, jika tidak Anda berisiko itu tidak diterima ke dalam standar.

Dengan kata lain, Anda harus memperkenalkan aturan ke standar pengkodean yang terlihat sah dan memiliki peluang bagus untuk diterima oleh anggota komite lainnya. Setelah proyek dimulai dan banyak jam kerja diinvestasikan dalam kode, Anda harus dapat menyalahgunakan aturan ini (misalnya, dengan teknis, atau dengan sangatinterpretasi literal) untuk menandai kode yang dinyatakan normal dan berkualitas baik sebagai melanggar standar. Jadi mereka harus berusaha keras untuk mendesain ulang, dan aturan akan menghalangi mereka sejak saat ini, tetapi karena aturan aktif untuk beberapa waktu sekarang, momentum murni akan menjaga peran ini tetap hidup, dan karena ada konflik yang signifikan kepentingan antara berbagai tingkat manajemen, manajer lain mungkin akan menjaga aturan hidup (mereka akan bodoh untuk mengakui kesalahan mereka!), karena itu menghambat perusahaan! Mwahahahahaaa!

Mencetak gol

Jawaban dengan suara tertinggi setelah sekitar 2 minggu sejak entri pertama yang valid menang. Saya punya ide untuk jawaban yang baik, tetapi saya hanya akan mempostingnya beberapa hari kemudian, karena orang lain mungkin akan datang ke ide yang sama, dan saya tidak ingin merampok mereka dari kesenangan. Tentu saja, jawaban saya sendiri tidak akan diterima di atas yang lain, apa pun nilainya.

Pemilih didorong untuk mencetak jawaban berdasarkan seberapa baik celah tersembunyi, dan seberapa frustasi para pengembang.

Peraturan dan ketentuan

  • Aturan atau aturan harus terlihat ditulis secara profesional, seperti pada contoh di atas
  • Aturan harus terlihat asli (sehingga hal-hal seperti "semua variabel harus mengandung setidaknya satu garis bawah, satu huruf besar, satu huruf kecil dan dua angka" tidak diterima. Mereka memang akan menghambat pengembang, tetapi kemungkinan besar tidak akan diterima oleh komite) dan jika pahala mereka tidak segera jelas, Anda harus memberikan alasan yang baik.
  • Anda harus dapat menemukan cara untuk menggunakan / menyalahgunakan aturan Anda untuk menyabot pengembang nanti. Anda dapat menyalahgunakan ambiguitas dalam aturan lain, atau Anda dapat menggunakan beberapa aturan yang tidak berbahaya sendiri, tetapi jahat sekali digabungkan!
  • Anda harus memposting penjelasan dalam tag spoiler di akhir posting Anda tentang bagaimana Anda bisa menyalahgunakan aturan
  • Bahasa yang digunakan tidak boleh bahasa esoterik. Bahasa yang banyak digunakan dalam proyek nyata harus dipilih, jadi bahasa dengan sintaksis mirip-C (bukan hal-hal seperti Golfscript) lebih disukai.
vsz
sumber
4
Python, Ruby, Haskell, Makefile, XML, dll. Adalah beberapa bahasa yang digunakan dalam banyak proyek nyata yang tidak memiliki sintaks seperti C.
kennytm
7
Pertanyaan ini tampaknya di luar topik karena ini bukan kontes pemrograman.
Peter Taylor
5
@PeterTaylor: definisi termasuk "Teka-teki pemrograman" yang tidak berarti jawabannya harus berupa kode perangkat lunak. Tidak ada dalam definisi situs itu tertulis bahwa ini hanya tentang "kontes pemrograman". Definisi tersebut adalah: "Teka-teki golf / Pemrograman kode / Kontes atau tantangan pemrograman lainnya" "
vsz
7
@PeterTaylor sepertinya kontes tentang pemrograman untuk saya; di polisi & perampok menantang perampok juga tidak memberi kode (dan jika argumen Anda adalah perampok berkomentar, maka pastikan untuk mengomentari pos meta yang menyarankan polisi yang berpisah dan perampok menantang dua pertanyaan terpisah)
John Dvorak
5
Saya memilih untuk membuka kembali. Sepertinya kami masih memiliki beberapa pertanyaan di mana kami tidak dapat menyetujui apakah mereka ada di topik. Ini mengingatkan saya pada seni terkait yang ditutup kemudian dibuka kembali dua kali. Saya punya ide untuk jawaban untuk pertanyaan ini dan sudah pasti terkait pemrograman. Pertanyaan ini bahkan cocok dengan 2 tag di situs.
hmatt1

Jawaban:

40

C / C ++

Aturan 1: konstanta oktal tidak boleh digunakan

Dasar pemikiran: konstanta oktal dapat menjadi penyebab kebingungan. Misalnya, pandangan sekilas ke garis const int coefficients[] = {132, 521, 013, 102};
mungkin melewatkan fakta, bahwa salah satu angka dalam array didefinisikan dalam oktal.

Jika Anda ingin menjadi lebih jahat, tambahkan yang berikut ini:

Aturan 2: konstanta heksadesimal hanya akan digunakan dalam konteks manipulasi bit.

Dasar Pemikiran: Jika konstanta mewakili nilai numerik, itu lebih mudah dibaca jika dalam desimal. Konstanta heksadesimal harus menunjukkan bahwa itu mewakili bit mask, bukan nilai numerik.

Bagaimana bisa disalahgunakan:

Ambil program sederhana berikut yang akan menambahkan 10 elemen pertama dari sebuah array. Kode ini tidak akan sesuai standar.

sum = 0;
for (i = 0; i < 10; i++) 
{
    sum += array[i];
}

Perhatikan, yaitu 0, per definisi, konstanta oktal. Per aturan 1, mengharuskannya ditulis sebagai 0x00 semua melalui kode itu membuat frustrasi. Per aturan 2, bahkan lebih membuat frustrasi.

vsz
sumber
1
Bisakah Anda menautkan ke definisi standar pengkodean yang mengatakan itu 0adalah konstanta oktal? Saya kira itu karena itu dimulai dengan karakter 0. Itu akan memperkuat argumen pedant hipotetis Anda.
xnor
16

Python

Aturan 1: Semua kode harus byte-dikompilasi menggunakan -OOflag, yang mengoptimalkan bytecode. Kami ingin bytecode yang dioptimalkan untuk ukuran dan efisiensi!

Aturan 2: Tes harus dijalankan terhadap "artefak" kode yang sama yang akan dimasukkan ke dalam produksi. Auditor kami memerlukan ini.

Menggunakan -OOmenghapus assertpernyataan. Dikombinasikan dengan aturan 2, ini secara efektif melarang penggunaan assertpernyataan dalam pengujian. Selamat bersenang-senang!

ErlVolton
sumber
Ini juga menghilangkan dokumen, yang berarti Anda tidak mendapatkan apa pun dari help()di REPL, dan pengujian REPL informal masih sedang diuji.
Kevin
Nggak. Jika Anda menulis kerangka kerja pengujian yang tepat, itu akan menggunakanunittest modul atau, yang mengimplementasikan pernyataannya sendiri tidak tergantung pada __debug__bendera. Namun, dokumen tidak akan berjalan diam-diam. Sneaky!
pppery
15

Ini untuk proyek Node.JS.

Bagian 3 - Kecepatan dan efisiensi sangat penting

Aturan 3.1: File harus dijaga maksimum 1kb. File yang lebih besar dari ini butuh waktu terlalu lama untuk diuraikan.

Aturan 3.2: Jangan membuat sarang fungsi lebih dari 3 level. Mesin V8 harus melacak banyak variabel, dan penutupan yang dalam seperti ini membuatnya bekerja lebih keras, memperlambat interpretasi umum.

Aturan 3.3: Hindari require()runaround.

Aturan 3.3.1: Modul require()apa pun tidak boleh require()sampai kedalaman lebih dari 3. require()Rantai dalam mahal baik dalam hal penggunaan dan kecepatan memori.

Aturan 3.3.2: Modul inti dihitung sebagai satu require(), tidak peduli berapa kali mereka secara require()internal.

Aturan 3.3.3: Modul eksternal dihitung sebagai maksimum 2 require()detik. Kami tidak dapat memberikan keringanan hukuman yang sama dengan modul inti, tetapi dapat mengasumsikan bahwa penulis modul menulis kode yang efisien.

Aturan 3.4: Hindari panggilan sinkron dengan cara apa pun. Ini sering memakan waktu lama, dan memblokir seluruh peristiwa untuk melanjutkan.

Bagaimana bisa disalahgunakan:

Aturan 3.1 dan 3.3 tidak bekerja dengan baik bersama. Dengan menjaga maksimum 1kb dan 3 require()detik di rantai, mereka akan kesulitan untuk berhasil.
Aturan 3.2 dan 3.4 hampir tidak kompatibel. 3.4 melarang panggilan sinkron; 3.2 membuat kerja asinkron lanjut menjadi sulit dengan membatasi jumlah panggilan balik.
Aturan 3.4, dalam semua kejujuran, aturan yang baik untuk diikuti secara nyata. 3.1, 3.2, dan 3.3 benar-benar palsu.

Scimonster
sumber
11

JavaScript (ECMAScript)

7.3.2: Literal ekspresi reguler

Literal ekspresi reguler tidak boleh digunakan. Secara khusus, kode sumber tidak boleh mengandung substring yang cocok dengan nonterminal RegularExpression yang didefinisikan di bawah ini.

RegularExpression     :: '/' RegularExpressionBody '/'
RegularExpressionBody :: [empty]
                         RegularExpressionBody [any-but-'/']

[kosong] cocok dengan string kosong dan [any-but - '/'] cocok dengan string karakter tunggal apa pun kecuali string yang mengandung '/' (slash,U+002F ).

Alasan

Ekspresi reguler sering tidak disarankan karena alasan keterbacaan. Seringkali lebih mudah untuk memahami kode dengan operasi string tradisional daripada dengan menggunakan ekspresi reguler. Namun yang lebih penting, banyak mesin ekspresi reguler menawarkan kinerja di bawah standar. Ekspresi reguler juga telah dikaitkan dengan masalah keamanan dalam konteks JavaScript.

Namun, Organisasi ™ mengakui bahwa ekspresi reguler sesekali adalah alat terbaik untuk pekerjaan itu. Karena itu, RegExpobjek itu sendiri tidak dilarang.

(Sintaks kutipan tata bahasa itu sendiri [bukan yang didefinisikannya] sesuai dengan spesifikasi ECMAScript. Tentu saja ini akan didefinisikan dengan lebih ketat pada titik lain dari spesifikasi hipotetis.)

Trik-nya

Program berikut tidak sesuai:

// sgn(x) is -1 if x < 0, +1 if x > 0, and 0 if x = 0.
function sgn(x) {
  return x > 0?  +1
       : x < 0?  -1
       :          0
}

Produksi untuk nonterminal RegularExpressionBody yang diberikan di atas menunjukkan cara yang umum untuk mengekspresikan daftar di BNF dengan mengandalkan rekursi eksplisit. Kuncinya di sini adalah bahwa saya "secara tidak sengaja" membiarkan string kosong sebagai RegularExpressionBody , sehingga string //dilarang dalam kode sumber. Tapi siapa yang butuh komentar satu baris? C89 dan CSS tampaknya baik-baik saja sementara hanya mengizinkan /* */memblokir komentar.

FireFly
sumber
15
Ini sebenarnya bahkan lebih jahat dari itu: kode mungkin tidak mengandung blok-komentar, atau lebih dari satu operator divisi per file.
Chromatix
Oh ya, kamu benar. Aku bahkan tidak memikirkan itu. : P
FireFly
5

C #

12.1 Metode statis yang memengaruhi status program dilarang

Ini karena sulit untuk secara andal menguji hasil dari metode statis, terutama yang mengubah keadaan tertentu.

12.2 Metode statis harus bersifat deterministik

Jika metode statis mengambil input dan memberikan output, hasilnya harus sama setiap kali metode statis dipanggil dengan input yang sama.

Mengapa

Titik masuk untuk program C # adalah metode statis privat 'utama'. Dengan aturan pertama ini sekarang dilarang karena aturan lupa untuk menyatakan bahwa hanya metode publik, dilindungi atau internal yang harus mengikuti aturan ini. Jika pengujian benar-benar menjadi perhatian, hanya metode publik yang harus mengikuti aturan 1. Utama juga dapat melanggar aturan 2 karena program akan memberikan kode kesalahan jika program gagal, ini dapat terjadi terlepas dari parameter input. Misalnya program mungkin tidak menemukan file atau mungkin memiliki ketergantungan pada sistem lain yang tidak diatur dengan benar.

sydan
sumber
4

JAWA / SPRING

4.2 Penggunaan Refleksi dalam Kode Produksi

Karena Refleksi dapat digunakan untuk mengakses bagian-bagian lain yang dilarang dari kode sumber kami, penggunaan refleksi dalam Kode Produksi sangat dilarang.

Trik-nya

Spring secara teknis menggunakan refleksi untuk membuat dan mengelola objek yang didukungnya. Dengan menerapkan aturan ini, semua utilitas Spring harus dihapus.

tfitzger
sumber
3

Pengkodean situs web

666.13 UTF-8 tidak boleh digunakan dan harus diganti oleh UTF-7
Dasar Pemikiran: UTF-7 lebih efisien daripada UTF-8, terutama ketika menargetkan pengguna dari negara-negara Arab yang kita lakukan.

Bagaimana bisa disalahgunakan:

HTML5 secara khusus melarang UTF-7. Itu artinya, browser modern tidak akan mendukungnya. Jika semua pengujian dilakukan pada browser seperti IE 11, tidak ada yang akan memperhatikan ini sampai semuanya terlambat.

Stefnotch
sumber
2

Operator Bitwise JavaScript

1.9 Anda tidak boleh menggunakan perkalian atau pembagian atau lantai kecuali jika mereka jauh lebih cepat daripada rekan bitwise mereka. Mereka harus diganti oleh operator bitwise <<, >> dan ~~ masing-masing.
Dasar Pemikiran: Operator bitwise lebih efisien.

Bagaimana bisa disalahgunakan:

Menggunakan << atau >> alih-alih perkalian atau pembagian akan menyebabkan masalah saat menangani angka besar. Juga, mereka mengabaikan prioritas operasi dan titik desimal. Double tilde akan mengembalikan nilai yang berbeda ketika Anda memberikan angka negatif.

Stefnotch
sumber
2
Saya pikir sudah jelas bahwa x = (x<<10) + (x<<8) + (x<<5) + (x<<4) + (x<<3) + (x)lebih rendah dalam segala hal (bahkan mungkin kecepatan) x *= 1337, dan mengganti pembagian dengan non-kekuatan dua dengan jumlah bithifts bahkan lebih buruk.
lirtosiast
@ Thomas Kwa saya mengedit jawaban saya dengan tepat. Terima kasih telah menunjukkan ini. Saya baru mengenal operator bitwise.
Stefnotch
1

JavaScript (ECMAScript)

7.3.1: Konvensi pengidentifikasi

Pembatasan ditempatkan pada pengidentifikasi tergantung pada apa jenis pengenal itu. Identifier dibagi menjadi tipe Variable , Constant , Function , dan Constructor ; lihat 5.3. Pembatasan diberikan di bawah ini.

  • Variabel: Karakter pertama harus berupa karakter huruf kecil. Kasing camel (lihat 1.3) harus digunakan untuk memisahkan kata-kata dalam pengidentifikasi.

  • Konstan: Pengidentifikasi hanya terdiri dari huruf besar dan garis bawah ('_', U+005F). Garis bawah harus digunakan untuk memisahkan kata dalam pengidentifikasi.

  • Fungsi: Fungsi harus mengikuti aturan yang sama dengan tipe Identifier .

  • Konstruktor: Karakter pertama harus berupa karakter huruf besar. Kasing camel (lihat 1.3) harus digunakan untuk memisahkan kata-kata dalam pengidentifikasi.

Alasan

Nama pengenal yang mudah dibaca sangat penting untuk pemeliharaan. Membatasi pengidentifikasi ke konvensi terkenal juga memudahkan transisi antara basis kode yang berbeda. Konvensi khusus ini dimodelkan setelah konvensi standar untuk bahasa pemrograman Java ™ [1] .

Trik-nya

Saya menyesal memberi tahu tim jQuery bahwa nama paling umum untuk "objek jQuery global" mereka berbenturan dengan konvensi nama ini. Untungnya, mereka sudah memikirkan hal itu dan memberikan keduanya $dan jQuerysebagai nama global yang merujuk pada objek yang sama. Saya membayangkan bahwa basis pengguna mungkin tidak tertarik untuk beralih dari $ke jQuerymana - mana.

FireFly
sumber
2
»Fungsinya harus mengikuti aturan yang sama dengan tipe Identifier .« - maksud Anda »sebagai tipe Variable «?
Paŭlo Ebermann