Sabotare gli standard di codifica [chiuso]


35

Esistono vari standard di codifica applicati alle società di software che hanno l'obiettivo di aumentare l'affidabilità del codice, la portabilità e, soprattutto, la leggibilità nel codice scritto congiuntamente da diversi sviluppatori.

Due esempi notevoli sono il MISRA C e lo standard C ++ sviluppato per il progetto JSF .

Questi sono di solito nella forma seguente, dopo aver specificato attentamente cosa significano le parole "must", "must", "should", "might", ecc.

Esempio:

Regola 50: le variabili in virgola mobile non devono essere verificate per l'eguaglianza o la disuguaglianza esatta.

Motivazione: Poiché i numeri in virgola mobile sono soggetti a errori di arrotondamento e di troncamento, l'eguaglianza esatta potrebbe non essere raggiunta, anche quando previsto.

Questi standard di codifica pongono delle restrizioni, di solito su un codice che sarebbe legale dal punto di vista del compilatore, ma è pericoloso o illeggibile ed è quindi "considerato dannoso".

Ora abusiamo di questo!

Sei accettato come membro di un piccolo comitato di standardizzazione presso la tua azienda, che ha lo scopo di progettare i nuovi standard di codifica che ogni sviluppatore dell'azienda dovrà utilizzare. All'insaputa degli altri, sei segretamente impiegato in un'organizzazione sinistra e hai la missione di sabotare la compagnia. Devi proporre una o più voci allo standard di codifica che in seguito ostacoleranno gli sviluppatori. Tuttavia, devi stare attento a non renderlo immediatamente evidente, altrimenti rischi di non essere accettato nello standard.

In altre parole, è necessario introdurre regole per lo standard di codifica che sembrano legittime e hanno buone probabilità di essere accettate dagli altri membri del comitato. Dopo che i progetti sono avviati e innumerevoli ore-uomo sono investiti nel codice, si dovrebbe essere in grado di abusare di queste regole (ad esempio, per un cavillo, o da un moltointerpretazione letterale) per contrassegnare il codice altrimenti normale e di buona qualità come contrario allo standard. Quindi devono impegnarsi molto per ridisegnarlo, e le regole li ostacoleranno da questo punto in poi, ma poiché le regole sono attive da un po 'di tempo ormai, il puro slancio manterrà in vita questi ruoli e poiché ci sono conflitti significativi di interessi tra diversi livelli di gestione, gli altri gestori probabilmente manterranno vive le regole (sarebbero sciocchi ad ammettere il loro errore!), ostacolando quindi la società! Mwahahahahaaa!

punteggio

La risposta più votata dopo circa 2 settimane dalla prima iscrizione valida vince. Ho un'idea per una buona risposta, ma la posterò solo pochi giorni dopo, poiché qualcun altro potrebbe venire alla stessa idea e non voglio privarli del piacere. Naturalmente, la mia risposta non sarà accettata sopra ogni altra, indipendentemente dal punteggio.

Gli elettori sono incoraggiati a valutare le risposte in base a quanto bene sono nascoste le scappatoie e quanto frustranti sarebbero per gli sviluppatori.

Norme e regolamenti

  • La regola o le regole devono apparire scritte professionalmente, come nell'esempio sopra
  • Le regole dovrebbero apparire autentiche (quindi cose come "tutte le variabili devono contenere almeno un carattere di sottolineatura, una lettera maiuscola, una lettera minuscola e due numeri" non sono accettate. Avrebbero effettivamente ostacolato gli sviluppatori, ma molto probabilmente non sarebbero state accettate da il comitato) e se il loro merito non è immediatamente evidente, dovresti dare una buona logica.
  • Dovresti essere in grado di trovare un modo per utilizzare / abusare delle tue regole per sabotare gli sviluppatori in seguito. Potresti abusare di qualsiasi ambiguità in altre regole, oppure potresti usare più regole che sono innocue da sole, ma diaboliche una volta combinate!
  • Dovresti pubblicare una spiegazione nei tag spoiler alla fine del tuo post su come potresti abusare delle regole
  • La lingua utilizzata non deve essere una lingua esoterica. Deve essere scelto un linguaggio ampiamente utilizzato in progetti reali, quindi sono preferiti i linguaggi con sintassi tipo C (invece di cose come Golfscript).

4
Python, Ruby, Haskell, Makefile, XML, ecc. Sono alcuni linguaggi utilizzati in molti progetti reali che non hanno una sintassi simile al C.
kennytm,

7
Questa domanda sembra essere fuori tema perché non è un concorso di programmazione.
Peter Taylor,

5
@PeterTaylor: la definizione include "Puzzle di programmazione" che non significa che la risposta deve essere un pezzo di codice software. Da nessuna parte nella definizione del sito è scritto che si tratta solo di "concorsi di programmazione". La definizione è: "Golf del codice / Puzzle di programmazione / Altri concorsi o sfide di programmazione" "
vsz

7
@PeterTaylor mi sembra una gara sulla programmazione; nelle sfide di poliziotti e ladri neanche i ladri programmano (e se la tua argomentazione è che i ladri commentano, assicurati di commentare il meta post che suggerisce di dividere le sfide di poliziotti e ladri in due domande separate)
John Dvorak,

5
Ho votato per riaprire. Sembra che abbiamo ancora alcune domande in cui non possiamo essere d'accordo sul fatto che siano in tema. Questo mi ricorda quello legato all'arte che è stato chiuso e poi riaperto due volte. Ho un'idea per una risposta a questa domanda ed è sicuramente legata alla programmazione. Questa domanda si adatta anche a 2 dei tag sul sito.
hmatt1,

Risposte:


40

C / C ++

Regola 1: le costanti ottali non devono essere utilizzate

Razionale: le costanti ottali possono essere fonte di confusione. Ad esempio, uno sguardo casuale sulla linea const int coefficients[] = {132, 521, 013, 102};
potrebbe non comprendere il fatto che uno dei numeri nell'array è definito in ottale.

Se vuoi essere ancora più malvagio, aggiungi quanto segue:

Regola 2: le costanti esadecimali devono essere utilizzate solo nel contesto della manipolazione dei bit.

Razionale: se una costante rappresenta un valore numerico, è più leggibile se è in decimale. Una costante esadecimale dovrebbe indicare che rappresenta una maschera di bit, non un valore numerico.

Come può essere abusato:

Prendi il seguente semplice programma che aggiungerà i primi 10 elementi di un array. Questo codice non sarebbe conforme allo standard.

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

Si noti, cioè 0, per definizione, una costante ottale. Per la regola 1, richiedere che sia scritto come 0x00 in tutto il codice è frustrante. Secondo la regola 2, ancora più frustrante.


1
Potresti collegarti alla definizione standard di codifica che dice che 0è una costante ottale? Presumo che sia perché inizia con il personaggio 0. Rafforzerebbe la tesi del tuo ipotetico pedante.
xnor


16

Pitone

Regola 1: tutto il codice deve essere compilato in byte usando il -OOflag, che ottimizza il bytecode. Vogliamo un bytecode ottimizzato per dimensioni ed efficienza!

Regola 2: i test devono essere eseguiti sullo stesso "artefatto" del codice che verrà messo in produzione. I nostri revisori lo richiedono.

L'uso -OOrimuove le assertistruzioni. In combinazione con la regola 2, ciò proibisce efficacemente l'uso delle assertdichiarazioni nei test. Divertiti!


Questo rimuove anche i documenti, il che significa che non si ottiene nulla dal help()REPL e che i test informali REPL stanno ancora testando.
Kevin,

No. Se si scrive un framework di test adeguato, utilizzerà il unittestmodulo o, che implementa le proprie asserzioni non dipendenti dalla __debug__bandiera. Tuttavia, i doctest non verranno eseguiti in silenzio. Subdolo!
pepery

15

Questo è per un progetto Node.JS.

Sezione 3 - Velocità ed efficienza sono essenziali

Regola 3.1: i file devono essere mantenuti ad un massimo di 1kb. I file più grandi di questo richiedono troppo tempo per essere analizzati.

Regola 3.2: Non annidare funzioni con profondità superiore a 3 livelli. Il motore V8 deve tenere traccia di molte variabili e chiusure profonde come questa rendono più duro il lavoro, rallentando l'interpretazione generale.

Regola 3.3: evitare i require()runaround.

Regola 3.3.1: qualsiasi modulo require()d non dovrebbe avere require()una profondità superiore a 3. Le require()catene profonde sono costose sia in termini di utilizzo della memoria che di velocità.

Regola 3.3.2: i moduli core contano come singoli require(), indipendentemente da quante volte require()internamente.

Regola 3.3.3: i moduli esterni contano come massimo 2 require()s. Non possiamo permetterci la stessa clemenza dei moduli core, ma possiamo presumere che gli autori dei moduli stiano scrivendo un codice efficiente.

Regola 3.4: evitare le chiamate sincrone a tutti i costi. Spesso ciò richiede molto tempo e impedisce il proseguimento dell'intero ciclo di eventi.

Come può essere abusato:

Le regole 3.1 e 3.3 non funzionano bene insieme. Mantenendo un massimo di 1kb e 3 require()s lungo la catena, saranno difficilmente riusciti.
Le regole 3.2 e 3.4 sono quasi incompatibili. 3.4 vieta le chiamate sincrone; 3.2 rende difficile il lavoro asincrono avanzato limitando il numero di callback.
La Regola 3.4 è, in tutta onestà, una regola che è buona da seguire per davvero. 3.1, 3.2 e 3.3 sono falsi completi.


11

JavaScript (ECMAScript)

7.3.2: letterali di espressioni regolari

I letterali delle espressioni regolari non devono essere utilizzati. In particolare, il codice sorgente non deve contenere alcuna sottostringa che corrisponda al non terminale RegularExpression definito di seguito.

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

[vuoto] corrisponde alla stringa vuota e [any-but - '/'] corrisponde a qualsiasi stringa a carattere singolo tranne quella contenente '/' (barra, U+002F).

Fondamento logico

Le espressioni regolari sono spesso scoraggiate per motivi di leggibilità. Spesso è più semplice comprendere il codice con le operazioni di stringa tradizionali piuttosto che ricorrere a espressioni regolari. Ancora più importante, tuttavia, molti motori di espressione regolare offrono prestazioni scadenti. Le espressioni regolari sono state anche associate a problemi di sicurezza nel contesto di JavaScript.

Tuttavia, Organization ™ riconosce che le espressioni regolari occasionalmente sono lo strumento migliore per il lavoro. Pertanto, l' RegExpoggetto stesso non è vietato.

(La sintassi dell'estratto grammaticale stesso [non quello che definisce] corrisponde a quella della specifica ECMAScript. Ciò sarebbe ovviamente definito in modo più rigoroso in un altro punto della specifica ipotetica.)

Il trucco

Il seguente programma non è conforme:

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

Le produzioni non regolari del RegularExpressionBody indicate sopra mostrano un modo comune di esprimere elenchi in BNF facendo affidamento sulla ricorsione esplicita. Il trucco qui è che acconsento "accidentalmente" alla stringa vuota come RegularExpressionBody , in modo tale che la stringa //sia vietata nel codice sorgente. Ma chi ha bisogno di commenti su una riga comunque? C89 e CSS sembrano fare tutto bene pur consentendo solo il /* */blocco dei commenti.


15
In realtà è persino più malvagio di così: il codice potrebbe non contenere commenti a blocchi, né più di un operatore di divisione per file.
Chromatix,

Oh sì, hai ragione. Non ci avevo nemmeno pensato. : P
FireFly,

5

C #

12.1 I metodi statici che influenzano lo stato del programma sono vietati

Questo perché è difficile testare in modo affidabile i risultati di un metodo statico, in particolare uno che cambia un certo stato.

12.2 I metodi statici devono essere deterministici

Se il metodo statico accetta un input e fornisce un output, il risultato deve essere lo stesso ogni volta che viene chiamato il metodo statico con lo stesso input.

Perché

Il punto di ingresso per un programma C # è il metodo statico privato 'principale'. Secondo la prima regola, ciò è ora vietato perché la regola dimentica di affermare che solo i metodi pubblici, protetti o interni dovrebbero seguire questa regola. Se la verifica è realmente la preoccupazione, solo i metodi pubblici dovrebbero seguire la regola 1. Main potrebbe anche infrangere la regola 2 poiché il programma fornirà un codice di errore se il programma fallisce, ciò può avvenire indipendentemente dai parametri di input. Ad esempio, il programma potrebbe non trovare un file o potrebbe avere dipendenze da altri sistemi che non sono stati impostati correttamente.


4

JAVA / SPRING

4.2 Uso della riflessione nel codice di produzione

Poiché Reflection può essere utilizzato per accedere a parti altrimenti limitate del nostro codice sorgente, l'uso di reflection nel Codice di produzione è severamente proibito.

Il trucco

Spring utilizza tecnicamente la riflessione per creare un'istanza e gestire gli oggetti che supporta. Applicando questa regola, è necessario rimuovere tutta l'utilità Spring.


3

Codifica del sito Web

666.13 UTF-8 non deve essere utilizzato e deve essere sostituito da UTF-7
Razionale: UTF-7 è più efficiente di UTF-8, specialmente quando si prendono di mira utenti di paesi arabi che facciamo.

Come può essere abusato:

HTML5 non consente specificamente UTF-7. Ciò significa che i browser moderni non lo supporteranno. Se tutti i test vengono eseguiti su un browser come IE 11, nessuno lo noterà fino a quando non è troppo tardi.


2

Operatori Bitwise JavaScript

1.9 Non devi usare moltiplicazioni o divisioni o pavimentazioni a meno che non siano considerevolmente più veloci delle loro controparti bit a bit. Devono essere sostituiti rispettivamente dagli operatori bit a bit <<, >> e ~~.
Motivazione: Gli operatori bit a bit sono più efficienti.

Come può essere abusato:

L'uso di << o >> invece della moltiplicazione o divisione causerà problemi nella gestione di grandi numeri. Inoltre, ignorano la precedenza dell'operazione e i punti decimali. La doppia tilde restituirà valori diversi quando si assegna un numero negativo.


2
Penso che sia già ovvio che x = (x<<10) + (x<<8) + (x<<5) + (x<<4) + (x<<3) + (x)sia inferiore in tutti i modi (possibilmente anche la velocità) x *= 1337e che sostituire la divisione con una non-potenza di due con somme di bit-shift sia anche peggio.
lirtosiast,

@Thomas Kwa Ho modificato la mia risposta in modo appropriato. Grazie per averlo segnalato. Sono nuovo per gli operatori bit a bit.
Stefnotch,

1

JavaScript (ECMAScript)

7.3.1: Convenzioni identificatore

Le restrizioni sono poste sugli identificatori a seconda del tipo di identificatore. Gli identificatori sono suddivisi nei tipi Variabile , Costante , Funzione e Costruttore ; vedi 5.3. Le restrizioni sono riportate di seguito.

  • Variabile: il primo carattere deve essere una lettera minuscola. Camel-case (vedi 1.3) dovrebbe essere usato per separare le parole all'interno di un identificatore.

  • Costante: l'identificatore deve essere composto solo da caratteri maiuscoli e caratteri di sottolineatura ('_',U+005F ). I trattini bassi dovrebbero essere usati per separare le parole all'interno di un identificatore.

  • Funzione: le funzioni devono seguire le stesse regole del tipo di identificatore .

  • Costruttore: il primo carattere deve essere un carattere maiuscolo. Camel-case (vedi 1.3) dovrebbe essere usato per separare le parole all'interno di un identificatore.

Fondamento logico

I nomi degli identificatori leggibili sono molto importanti per la manutenibilità. Limitare gli identificatori a convenzioni ben note facilita anche la transizione tra basi di codice diverse. Queste convenzioni particolari sono modellate sulle convenzioni standard per il linguaggio di programmazione Java ™ [1] .

Il trucco

Mi dispiace informare il team di jQuery che il nome più comune per il loro "oggetto jQuery globale" si scontra con questa convenzione sui nomi. Fortunatamente, ci hanno già pensato e forniscono entrambi $e jQuerycome nomi globali che si riferiscono allo stesso oggetto. Immagino che la base di utenti potrebbe non essere così ansiosi di passare da $a jQuerytutto il mondo, però.


2
»Le funzioni devono seguire le stesse regole del tipo Identificatore .« - Intendi »come tipo di variabile «?
Paŭlo Ebermann,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.