Саботаж стандартів кодування [закрито]


35

У програмних компаніях існують різні стандарти кодування, які мають на меті підвищити надійність коду, портативність і, що найголовніше, читабельність у коді, написаному спільно різними розробниками.

Два помітних приклади - MISRA C та стандарт C ++, розроблений для проекту JSF .

Зазвичай вони знаходяться в наступній формі, після ретельного уточнення, що означають слова "повинен", "повинен", "повинен", "міг" тощо:

Приклад:

Правило 50: Змінні з плаваючою точкою не перевіряються на точну рівність або нерівність.

Обґрунтування: Оскільки номери з плаваючою комою підлягають помилкам округлення та укорочення, точної рівності може бути досягнуто навіть тоді, коли очікується.

Ці стандарти кодування створюють обмеження, як правило, щодо коду, який був би законним з точки зору компілятора, але він небезпечний чи нечитабельний, і тому "вважається шкідливим".

Тепер давайте зловживати цим!

Вас приймають як члена невеликого комітету зі стандартизації у вашій компанії, який призначений для розробки нових стандартів кодування, який повинен використовувати кожен розробник компанії. Якщо ви не знаєте інших, ви таємно працюєте в зловісній організації і ставите своєю місією саботувати компанію. Вам потрібно запропонувати одну або кілька записів до стандарту кодування, що згодом перешкоджатиме розробникам. Однак ви повинні бути обережними, щоб не зробити це відразу очевидним, інакше ви ризикуєте його не прийняти до стандарту.

Іншими словами, ви повинні ввести правила до стандарту кодування, які виглядають законними та мають шанси бути прийнятим іншими членами комітету. Після запуску проектів і вкладення в код незліченних кількох годин-годин, ви можете мати можливість зловживати цими правилами (наприклад, технікою або дужедослівне тлумачення), щоб позначити інакше нормальний і якісний код як такий, що суперечить стандарту. Тому вони повинні докласти чимало зусиль, щоб його переробити, і правила будуть перешкоджати їм з цього моменту, але оскільки правила діють досить довго, чистий імпульс збереже ці ролі в живих, і оскільки існують значні конфлікти Інтереси між різними рівнями управління, інші менеджери, ймовірно, зберігатимуть живі правила (було б нерозумно визнати свою помилку!), тому заважаючи компанії! Mwahahahahaaa!

Оцінка балів

Найвища відповідь, яка проголосується, приблизно через 2 тижні від першого виграного результату. У мене є ідея для гарної відповіді, але я опублікую її лише через кілька днів, як хтось інший може прийти до цієї ж ідеї, і я не хочу їх позбавляти від задоволення. Звичайно, моя власна відповідь не буде прийнята вище за будь-яку іншу, незалежно від оцінки.

Виборцям пропонується набирати відповіді, виходячи з того, наскільки добре проробляються лазівки та наскільки вони неприємні для розробників.

Правила і норми

  • Правило або правила повинні виглядати професійно написаними, як у наведеному вище прикладі
  • Правила повинні виглядати справжніми (тому такі речі, як "усі змінні повинні містити щонайменше одну підкреслення, одну верхню літеру, одну малу літеру та два цифри" , не приймаються. Вони дійсно перешкоджають розробникам, але, швидше за все, не будуть прийняті комітет), і якщо їх заслуга не відразу очевидна, ви повинні дати гарне обгрунтування.
  • Ви маєте змогу знайти спосіб використання / зловживання своїми правилами для саботажу розробників пізніше. Ви можете зловживати будь-якою неоднозначністю в інших правилах, або можете скористатися кількома правилами, які самі по собі нешкідливі, але одночасно дьявольські!
  • Ви повинні розмістити пояснення в тегах спойлерів у кінці публікації про те, як ви могли зловживати правилами
  • Використовувана мова не повинна бути езотеричною мовою. Мова, яка широко використовується в реальних проектах, повинна бути обрана, тому мови з C-подібним синтаксисом (замість таких речей, як Golfscript).

4
Python, Ruby, Haskell, Makefile, XML тощо - це деякі мови, які використовуються у багатьох реальних проектах, у яких немає синтаксису подібного С.
kennytm

7
Це питання видається поза темою, оскільки це не конкурс програмування.
Пітер Тейлор

5
@PeterTaylor: визначення включає в себе "Загадки програмування", що не означає, що відповідь має бути частиною програмного коду. Ніде у визначенні сайту не написано, що мова йде лише про "конкурси програмування". Визначення таке: "Код гольфу / Головоломки програмування / Інші змагання з програмування чи виклики" "
vs

7
@PeterTaylor мені схоже на конкурс щодо програмування; у поліцейських та грабіжників виклики грабіжників також не кодують (і якщо ваш аргумент полягає в тому, що грабіжники коментують, то не забудьте прокоментувати мета-пост, який пропонує розділити копів та розбійників на два окремих питання)
Джон Дворак

5
Я проголосував за повторне відкриття. Схоже, у нас ще є деякі питання, де ми не можемо домовитись, чи є вони на тему. Це нагадує мені те мистецтво, яке закрилося, а потім було відкрито двічі. У мене є ідея відповіді на це питання, і це, безумовно, пов'язано з програмуванням. Це питання навіть відповідає 2 тегам на сайті.
hmatt1

Відповіді:


40

C / C ++

Правило 1: восьмеричні константи не повинні використовуватися

Обгрунтування: восьмеричні константи можуть бути причиною плутанини. Наприклад, випадковий погляд на лінію const int coefficients[] = {132, 521, 013, 102};
може пропустити той факт, що одне з чисел у масиві визначено у восьмериці.

Якщо ви хочете бути ще злішими, додайте наступне:

Правило 2: Шістнадцяткові константи повинні використовуватися лише в разі маніпуляції бітом.

Обґрунтування: Якщо константа представляє числове значення, вона є більш читаною, якщо вона знаходиться в десятковій. Шістнадцяткова константа повинна вказувати, що вона являє собою бітову маску, а не числове значення.

Як це можна зловживати:

Візьміть наступну просту програму, яка додасть перші 10 елементів масиву. Цей код не був би стандартним.

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

Зауважте, тобто 0, за визначенням, вісімкова константа. Згідно з правилом 1, вимагаючи, щоб він писався як 0x00 через весь код, засмучує. За правилом 2 ще більше засмучує.


1
Чи можете ви зв’язати стандартне визначення кодування, яке говорить, що 0це вісімкова константа? Я припускаю, що це тому, що це починається з характеру 0. Це посилить міркування вашого гіпотетичного педанта.
xnor


16

Пітон

Правило 1: Весь код повинен бути складений в байтах, використовуючи -OOпрапор, який оптимізує байт-код. Ми хочемо оптимізувати байт-код для розміру та ефективності!

Правило 2: Тести повинні бути виконані на тому ж "артефакті" коду, який буде поставлений у виробництво. Наші аудитори вимагають цього.

Використання -OOвидаляє assertзаяви. У поєднанні з правилом 2 це ефективно забороняє використання assertоператорів у тестах. Веселіться!


Це також видаляє документи, тобто ви не отримаєте нічого з help()REPL, а неформальне тестування REPL все ще тестується.
Кевін

Ні. Якщо ви пишете належний тестовий фреймворк, він використовуватиме unittestабо модуль, який реалізує власні твердження незалежно від __debug__прапора. Однак доктести мовчки не працюватимуть. Підлий!
pppery

15

Це для проекту Node.JS.

Розділ 3 - Швидкість та ефективність є суттєвими

Правило 3.1: Файли мають зберігатися максимум до 1 Кб. Файли, більші за цей, займають сильний розбір.

Правило 3.2: Не гніздіть функції більше ніж на 3 рівні. Двигун V8 повинен відслідковувати безліч змінних, а глибокі закриття на кшталт цього ускладнюють роботу, уповільнюючи загальну інтерпретацію.

Правило 3.3: Уникайте require()покровів.

Правило 3.3.1: Будь-які модулі require()d не require()повинні мати глибину більше 3. Глибокі require()ланцюги є дорогими як з точки зору використання пам'яті, так і швидкості.

Правило 3.3.2: Основні модулі рахуються як єдині require(), незалежно від того, скільки разів вони require()внутрішні.

Правило 3.3.3: Зовнішні модулі вважаються максимум 2 require()с. Ми не можемо дозволити собі таку ж поблажливість, що і для основних модулів, але можна припустити, що автори модулів пишуть ефективний код.

Правило 3.4: Уникайте синхронних дзвінків за будь-яку ціну. Вони часто займають багато часу і блокують продовження циклу подій.

Як це можна зловживати:

Правила 3.1 та 3.3 не працюють разом. Зберігаючи максимум 1 кбіт і 3 require()с по ланцюгу, вони будуть сильно натиснуті на успіх.
Правила 3.2 та 3.4 майже не сумісні. 3.4 забороняє синхронні дзвінки; 3.2 ускладнює вдосконалену асинхронну роботу через обмеження кількості зворотних викликів.
Правило 3.4 є, чесно кажучи, правилом, якого слід добре дотримуватися реально. 3.1, 3.2 та 3.3 є повними фальшивими.


11

JavaScript (ECMAScript)

7.3.2: Літерали регулярного вираження

Літерали регулярного виразу не повинні використовуватися. Зокрема, вихідний код не повинен містити підрядків, що відповідають нетерміналу RegularExpression, визначеному нижче.

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

[порожній] відповідає порожньому рядку, а [будь-який - але - '/'] відповідає будь-якій рядку з одним символом, крім тієї, що містить '/' (коса риса, U+002F).

Обґрунтування

Регулярні висловлювання часто не рекомендуються з міркувань читабельності. Часто простіше зрозуміти код за допомогою традиційних рядкових операцій, ніж вдаючись до регулярних виразів. Що ще важливіше, але багато двигуни регулярної експресії пропонують низьку продуктивність. Регулярні вирази також були пов'язані з проблемами безпеки в контексті JavaScript.

Однак Організація ™ визнає, що регулярні вирази час від часу є найкращим інструментом для роботи. Тому сам RegExpоб’єкт не заборонений.

(Синтаксис граматичного уривку (не той, який він визначає) відповідає синтаксису специфікації ECMAScript. Це, звичайно, буде визначено більш чітко в іншому пункті гіпотетичної специфікації.)

Хитрість

Наступна програма не відповідає:

// 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
}

Виробники для нетерміналу RegularExpressionBody, наведені вище, показують загальний спосіб вираження списків у BNF, спираючись на явну рекурсію. Хитрість тут полягає в тому, що я "випадково" дозволяю порожній рядок як RegularExpressionBody , таким чином, що рядок //заборонено у вихідному коді. Але кому взагалі потрібні однорядкові коментарі? Здається, у C89 та CSS все добре, дозволяючи лише /* */блокувати коментарі.


15
Це насправді навіть більше зла, ніж це: код може містити не блокові коментарі, ні більше одного оператора поділу на файл.
Хроматикс

О так, ти маєш рацію. Я навіть про це не думав. : P
FireFly

5

C #

12.1 Статичні методи, що впливають на стан програми, заборонені

Це тому, що важко перевірити результати статичного методу, особливо такого, який змінює деякий стан.

12.2 Статичні методи повинні бути детермінованими

Якщо статичний метод приймає вхід і дає вихід, результат повинен бути однаковим кожен раз, коли статичний метод викликається з одним і тим же входом.

Чому?

Точкою входу для програми C # є приватний статичний метод "main". За першим правилом це зараз заборонено, оскільки це правило забуває заявляти, що лише публічні, захищені чи внутрішні методи повинні слідувати цьому правилу. Якщо тестування насправді викликає занепокоєння, лише публічні методи повинні дотримуватися правила 1. Основний також може порушити правило 2, оскільки програма видасть код помилки, якщо програма не працює, це може статися незалежно від вхідних параметрів. Наприклад, програма може не знайти файл або може мати залежність від інших систем, які неправильно налаштовані.


4

ЯВА / ВЕСНА

4.2 Використання відображення у виробничому кодексі

Оскільки відображення може використовуватися для доступу до інших частин нашого вихідного коду, використання відображення у виробничому кодексі категорично заборонено.

Хитрість

Весна технічно використовує відображення для інстанціювання та управління об'єктами, які він підтримує. Виконуючи це правило, всю утиліту Spring потрібно було б видалити.


3

Кодування веб-сайтів

666.13 UTF-8 не слід застосовувати і замінювати його
обґрунтуванням UTF-7 : UTF-7 є більш ефективним, ніж UTF-8, особливо коли націлено на користувачів з арабських країн, які ми робимо.

Як це можна зловживати:

HTML5 спеціально забороняє UTF-7. Це означає, що сучасні браузери не підтримують це. Якщо все тестування буде виконано в браузері, такому як IE 11, ніхто цього не помітить, поки не пізно.


2

Бітові оператори JavaScript

1.9. Ви не повинні використовувати множення, ділення чи настил, якщо вони не будуть значно швидшими, ніж їхні побіжні аналоги. Вони повинні бути замінені операторами побітової передачі <<, >> і ~~ відповідно.
Обгрунтування: бітові оператори ефективніші.

Як це можна зловживати:

Використання << або >> замість множення чи ділення спричинить проблеми при роботі з великою кількістю. Крім того, вони ігнорують пріоритет операцій та десяткових знаків. Подвійний нахил повертає різні значення, коли ви дасте йому від’ємне число.


2
Я думаю, що вже очевидно, що x = (x<<10) + (x<<8) + (x<<5) + (x<<4) + (x<<3) + (x)вона поступається всіма способами (можливо, навіть швидкістю) x *= 1337, і що замінити поділ на несильну силу двох з сумою дворозмінних змін ще гірше.
lirtosiast

@Thomas Kwa Я відповідним чином відредагував свою відповідь. Дякую, що вказали на це. Я новачок у розрядних операторах.
Стефнотч

1

JavaScript (ECMAScript)

7.3.1: Умови ідентифікаторів

Обмеження ставляться до ідентифікаторів залежно від типу ідентифікатора. Ідентифікатори поділяються на типи змінної , постійної , функціональної та конструкторної ; див. 5.3. Обмеження наведено нижче.

  • Змінна: Перший символ повинен бути символом малої літери. Виділення верблюда (див. 1.3) слід використовувати для розділення слів в ідентифікаторі.

  • Постійний: Ідентифікатор повинен містити лише великі літери та підкреслення ('_', U+005F). Підкреслення слід використовувати для розділення слів в ідентифікаторі.

  • Функція: Функції повинні відповідати тим же правилам, що і тип Ідентифікатора .

  • Конструктор: Перший символ повинен бути великим літером. Виділення верблюда (див. 1.3) слід використовувати для розділення слів в ідентифікаторі.

Обґрунтування

Читані імена ідентифікаторів дуже важливі для ремонту. Обмеження ідентифікаторів відомими умовами також полегшує перехід між різними базами коду. Ці конкретні конвенції моделюються за стандартними умовами для мови програмування Java ™ [1] .

Хитрість

Я шкодую, щоб повідомити команду jQuery, що найпоширеніша назва їхнього "глобального об'єкта jQuery" зіткнеться з цією умовою імені. На щастя, вони вже подумали про це і надають як $і jQueryглобальні імена, що посилаються на той самий об’єкт. Я вважаю , що UserBase може бути не так сильно , щоб перейти від $до jQueryвсюди, хоча.


2
»Функції повинні відповідати тим же правилам, що і тип Ідентифікатора .« - Ви маєте на увазі »як тип змінної «?
Paŭlo Ebermann
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.