Saboter les normes de codage [fermé]

35

Diverses normes de codage appliquées par les éditeurs de logiciels ont pour objectif d'accroître la fiabilité, la portabilité et, plus important encore, la lisibilité du code écrit conjointement par différents développeurs.

MISRA C et le standard C ++ développés pour le projet JSF sont deux exemples notables .

Celles-ci se présentent généralement sous la forme suivante, après avoir soigneusement précisé ce que signifient les mots "doit", "doit", "devrait", "pourrait", etc.

Exemple:

Règle 50: Les variables à virgule flottante ne doivent pas être testées pour une égalité ou une inégalité exacte.

Justification: étant donné que les nombres en virgule flottante sont sujets à des erreurs d’arrondi et de troncature, il se peut que l’égalité exacte ne soit pas atteinte, même si prévu.

Ces normes de codage posent des restrictions, généralement sur des codes qui seraient légaux du point de vue du compilateur, mais ils sont dangereux ou illisibles, et sont donc "considérés comme nuisibles".

Maintenant, abusons de cela!

Vous êtes accepté en tant que membre d'un petit comité de normalisation de votre société, qui est conçu pour concevoir les nouvelles normes de codage que chaque développeur de la société devra utiliser. À l'insu des autres, vous êtes secrètement à l'emploi d'une organisation sinistre et vous avez pour mission de saboter l'entreprise. Vous devez proposer une ou plusieurs entrées à la norme de codage qui gêneront plus tard les développeurs. Cependant, vous devez faire attention à ne pas rendre ceci immédiatement évident, sinon vous risqueriez de ne pas être accepté dans la norme.

En d'autres termes, vous devez introduire dans la norme de codage des règles qui semblent légitimes et ont de bonnes chances d'être acceptées par les autres membres du comité. Une fois les projets ont commencé et un nombre incalculable d'heures sont investis dans le code, vous devriez être en mesure d'abuser de ces règles (par exemple, par un détail technique, ou par une trèsinterprétation littérale) pour signaler un code par ailleurs normal et de bonne qualité comme étant contraire à la norme. Ils doivent donc faire beaucoup d’efforts pour le remodeler, et les règles les en empêcheront à partir de ce moment-là, mais comme ces règles sont en vigueur depuis un certain temps déjà, un pur élan gardera ces rôles en vie et des conflits importants d’intérêts entre les différents niveaux de direction, les autres dirigeants vont probablement maintenir les règles en vigueur (ils seraient fous d’admettre leur erreur!), gênant ainsi l’entreprise! Mwahahahahaaa!

Notation

La réponse la plus votée après environ deux semaines à compter de la première entrée valide l'emporte. J'ai une bonne idée de réponse, mais je ne la posterai que quelques jours plus tard, car quelqu'un d'autre pourrait en venir à la même idée, et je ne veux pas leur voler le plaisir. Bien sûr, ma propre réponse ne sera pas acceptée, aucune autre, peu importe le score.

Les électeurs sont encouragés à noter les réponses en fonction de la manière dont les échappatoires sont cachées et de la frustration qu'elles ressentent pour les développeurs.

Règles et règlements

  • La règle ou les règles doivent avoir une apparence professionnelle, comme dans l'exemple ci-dessus
  • Les règles doivent avoir l’air authentique (de sorte que des choses comme "toutes les variables doivent contenir au moins un trait de soulignement, une lettre majuscule, une lettre minuscule et deux chiffres" ne sont pas acceptées. Elles entraveraient certes les développeurs, mais ne seraient probablement pas acceptées par du comité) et si leur mérite n’est pas immédiatement évident, vous devez justifier votre décision.
  • Vous devriez être capable de trouver un moyen d’utiliser / d’abuser de vos règles pour saboter ultérieurement les développeurs. Vous pouvez abuser de toute ambiguïté dans d'autres règles ou utiliser plusieurs règles inoffensives, mais diaboliques une fois combinées!
  • Vous devriez poster une explication dans les balises spoiler à la fin de votre message sur la manière dont vous pourriez abuser des règles.
  • La langue utilisée ne doit pas être une langue ésotérique. Une langue largement utilisée dans les projets réels doit être choisie, donc les langues avec une syntaxe de type C (au lieu de choses comme Golfscript) sont préférées.
vsz
la source
4
Python, Ruby, Haskell, Makefile, XML, etc. sont des langages utilisés dans de nombreux projets réels sans syntaxe C-like.
Kennytm
7
Cette question semble être hors sujet car ce n'est pas un concours de programmation.
Peter Taylor
5
@PeterTaylor: la définition inclut "la programmation de puzzles", ce qui ne signifie pas que la réponse doit être un morceau de code logiciel. Nulle part dans la définition du site il est écrit qu'il ne s'agit que de "concours de programmation". La définition est la suivante: "Code golf / Programmation puzzles / Autres concours ou défis de programmation" "
vsz
7
@PeterTaylor, cela ressemble à un concours sur la programmation pour moi; dans les défis des flics et des cambrioleurs, les voleurs ne codent pas non plus (et si votre argument est que les cambrioleurs commentent, assurez-vous de commenter le méta-post qui suggère de séparer les défis des flics et des cambrioleurs en deux questions distinctes)
John Dvorak
5
J'ai voté pour rouvrir. Il semble que nous ayons encore des questions pour lesquelles nous ne pouvons pas nous mettre d'accord sur le fait qu'elles soient ou non sur un sujet. Cela me rappelle celui lié à l'art qui a été fermé puis rouvert deux fois. J'ai une idée de réponse à cette question et c'est certainement lié à la programmation. Cette question correspond même à 2 des tags sur le site.
hmatt1

Réponses:

40

C / C ++

Règle 1: les constantes octales ne doivent pas être utilisées

Justification: les constantes octales peuvent être source de confusion. Par exemple, un coup d'œil occasionnel sur la ligne const int coefficients[] = {132, 521, 013, 102};
peut passer à côté du fait que l'un des nombres du tableau est défini en octal.

Si vous voulez être encore plus pervers, ajoutez ce qui suit:

Règle 2: les constantes hexadécimales ne doivent être utilisées que dans le contexte de la manipulation de bits.

Justification: Si une constante représente une valeur numérique, elle est plus lisible si elle est décimale. Une constante hexadécimale doit indiquer qu’elle représente un masque de bits et non une valeur numérique.

Comment peut-on en abuser:

Prenez le programme simple suivant qui ajoutera les 10 premiers éléments d’un tableau. Ce code ne serait pas conforme à la norme.

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

Notez que 0, par définition, une constante octale. Par la règle 1, exiger qu’il soit écrit en tant que 0x00 tout au long du code est frustrant. Par règle 2, encore plus frustrant.

vsz
la source
1
Pourriez-vous établir un lien avec la définition de norme de codage qui dit qu'il 0s'agit d'une constante octale? Je présume que c'est parce que cela commence par le caractère 0. Cela renforcerait l'argument de votre hypothétique pédant.
xnor
16

Python

Règle 1: tout le code doit être compilé en octets à l'aide de l' -OOindicateur, qui optimise le bytecode. Nous voulons optimiser le bytecode pour sa taille et son efficacité!

Règle 2: Les tests doivent être exécutés sur le même "artefact" de code qui sera mis en production. Nos auditeurs l'exigent.

Utilisation -OOsupprime les assertdéclarations. Combiné à la règle 2, cela interdit efficacement l'utilisation de assertdéclarations dans les tests. S'amuser!

ErlVolton
la source
Cela supprime également les docstrings, ce qui signifie que vous ne tirez rien help()du REPL, et le test informel de REPL est toujours en cours de test.
Kevin
Nan. Si vous écrivez un cadre de test approprié, il utilisera le unittestmodule ou, qui implémentera ses propres assertions ne dépendant pas de l' __debug__indicateur. Les médecins ne fonctionneront pas silencieusement cependant. Sournois!
pppery
15

Ceci est pour un projet Node.JS.

Section 3 - La rapidité et l'efficacité sont essentielles

Règle 3.1: Les fichiers doivent être conservés au maximum à 1 Ko. Les fichiers plus gros que cela prennent trop de temps à analyser.

Règle 3.2: Ne pas imbriquer les fonctions de plus de 3 niveaux. Le moteur V8 doit garder en mémoire de nombreuses variables, et les fermetures profondes comme celle-ci rendent le travail plus difficile, ce qui ralentit l'interprétation générale.

Règle 3.3: Évitez les require()runarounds.

Règle 3.3.1: Les modules require()d ne doivent pas require()dépasser une profondeur de 3. Les require()chaînes profondes coûtent cher à la fois en termes d’utilisation de la mémoire et de vitesse.

Règle 3.3.2: Les modules de base comptent comme un seul require(), quel que soit leur nombre en require()interne.

Règle 3.3.3: Les modules externes comptent pour un maximum de 2 require()s. Nous ne pouvons pas nous permettre la même clémence qu'avec les modules de base, mais pouvons supposer que les auteurs de modules écrivent du code efficace.

Règle 3.4: Évitez les appels synchrones à tout prix. Celles-ci prennent souvent beaucoup de temps et empêchent toute la boucle d'événement de se poursuivre.

Comment peut-on en abuser:

Les règles 3.1 et 3.3 ne fonctionnent pas bien ensemble. En conservant un maximum de 1 Ko et 3 require()secondes dans la chaîne, ils auront du mal à réussir.
Les règles 3.2 et 3.4 sont presque incompatibles. 3.4 interdit les appels synchrones; 3.2 rend le travail asynchrone avancé difficile en limitant le nombre de rappels.
La règle 3.4 est, en toute honnêteté, une règle qu'il est bon de suivre pour de vrai. 3.1, 3.2 et 3.3 sont des faux complets.

Scimonster
la source
11

JavaScript (ECMAScript)

7.3.2: Littéraux d'expression régulière

Les littéraux d'expression régulière ne doivent pas être utilisés. Plus précisément, le code source ne doit contenir aucune sous-chaîne correspondant au terminal NormalExpression défini ci-dessous.

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

[empty] correspond à la chaîne vide et [any-but - '/'] à toute chaîne d'un seul caractère, à l'exception de celle contenant '/' (barre oblique, U+002F).

Raisonnement

Les expressions régulières sont souvent découragées pour des raisons de lisibilité. Il est souvent plus facile de comprendre le code avec les opérations de chaîne traditionnelles plutôt que de recourir à des expressions régulières. Plus important encore, de nombreux moteurs d’expression régulière offrent des performances inférieures à la moyenne. Les expressions régulières ont également été associées à des problèmes de sécurité dans le contexte de JavaScript.

Toutefois, l'Organisation reconnaît ™ que les expressions régulières de temps en temps est le meilleur outil pour le travail. Par conséquent, l' RegExpobjet lui-même n'est pas interdit.

(La syntaxe de l'extrait de grammaire elle-même [et non celle qu'il définit] correspond à celle de la spécification ECMAScript. Cela serait bien entendu défini plus rigoureusement à un autre point de la spécification hypothétique.)

L'astuce

Le programme suivant est 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
}

Les productions pour le non-terminal NormalExpressionBody données ci-dessus montrent une manière courante d’exprimer des listes dans BNF en s’appuyant sur une récursion explicite. L'astuce ici est que j'autorise "accidentellement" la chaîne vide en tant que RegularExpressionBody , de sorte que la chaîne //est interdite dans le code source. Mais qui a besoin de commentaires d'une seule ligne de toute façon? C89 et CSS semblent bien fonctionner en n'autorisant que le /* */blocage de commentaires.

Luciole
la source
15
En réalité, c'est encore plus pervers que cela: le code ne peut pas non plus contenir de commentaires de bloc, ni plus d'un opérateur de division par fichier.
Chromatix
Oh oui, tu as raison. Je n'y ai même pas pensé. : P
FireFly
5

C #

12.1 Les méthodes statiques qui affectent l'état du programme sont interdites

En effet, il est difficile de tester de manière fiable les résultats d'une méthode statique, notamment celle qui modifie un état.

12.2 Les méthodes statiques doivent être déterministes

Si la méthode statique prend une entrée et donne une sortie, le résultat doit être identique à chaque fois que la méthode statique est appelée avec la même entrée.

Pourquoi

Le point d'entrée d'un programme C # est la méthode statique privée 'main'. Par la première règle, ceci est maintenant interdit car la règle oublie de déclarer que seules les méthodes publiques, protégées ou internes doivent suivre cette règle. Si le test est vraiment la préoccupation, seules les méthodes publiques doivent suivre la règle 1. Main peut également enfreindre la règle 2 car le programme donnera un code d'erreur si le programme échoue, cela peut se produire indépendamment des paramètres d'entrée. Par exemple, le programme peut ne pas trouver un fichier ou peut avoir des dépendances sur d'autres systèmes qui ne sont pas configurés correctement.

Sydan
la source
4

JAVA / PRINTEMPS

4.2 Utilisation de la réflexion dans le code de production

Parce que Reflection peut être utilisé pour accéder à des parties autrement restreintes de notre code source, l'utilisation de la réflexion dans le Code de production est strictement interdite.

L'astuce

Spring utilise techniquement la réflexion pour instancier et gérer les objets qu'il prend en charge. En appliquant cette règle, tout l'utilitaire Spring devrait être supprimé.

tfitzger
la source
3

Encodage de site Web

666.13 UTF-8 ne doit pas être utilisé et doit être remplacé par UTF-7.
Justification: UTF-7 est plus efficace que UTF-8, en particulier lorsqu'il est destiné aux utilisateurs de pays arabes.

Comment peut-on en abuser:

HTML5 interdit spécifiquement UTF-7. Cela signifie que les navigateurs modernes ne le prendront pas en charge. Si tous les tests sont effectués sur un navigateur tel que IE 11, personne ne le remarquera jusqu'à ce qu'il soit trop tard.

Stefnotch
la source
2

Opérateurs JavaScript au niveau des bits

1.9 Vous ne devez pas utiliser la multiplication, la division ou le revêtement de sol à moins qu’ils soient considérablement plus rapides que leurs homologues au niveau des bits. Ils doivent être remplacés par les opérateurs au niveau des bits <<, >> et ~~ respectivement.
Justification: Les opérateurs au niveau du bit sont plus efficaces.

Comment peut-on en abuser:

L'utilisation de << ou >> au lieu de la multiplication ou de la division entraînera des problèmes lors du traitement de grands nombres. En outre, ils ignorent la priorité des opérations et les points décimaux. Le double tilde renverra des valeurs différentes lorsque vous lui donnerez un nombre négatif.

Stefnotch
la source
2
Je pense qu'il est déjà évident que ce qui x = (x<<10) + (x<<8) + (x<<5) + (x<<4) + (x<<3) + (x)est inférieur à tous les égards (peut-être même à la vitesse) x *= 1337, et que remplacer la division par une non-puissance de deux par des sommes de bitshifts est encore pire.
lirtosiast
@Thomas Kwa J'ai modifié ma réponse de manière appropriée. Merci de l'avoir signalé. Je suis nouveau aux opérateurs de bitwise.
Stefnotch
1

JavaScript (ECMAScript)

7.3.1: Conventions d'identifiant

Des restrictions sont imposées sur les identificateurs en fonction de leur type. Les identifiants sont répartis dans les types Variable , Constante , Fonction et Constructeur . voir 5.3. Les restrictions sont indiquées ci-dessous.

  • Variable: le premier caractère doit être une lettre minuscule. Les chameaux (voir 1.3) doivent être utilisés pour séparer les mots d'un identifiant.

  • Constante: L'identifiant ne doit comporter que des lettres majuscules et des traits de soulignement ('_', U+005F). Les traits de soulignement doivent être utilisés pour séparer les mots d'un identifiant.

  • Fonction: Les fonctions doivent suivre les mêmes règles que le type d' identifiant .

  • Constructeur: Le premier caractère doit être une lettre majuscule. Les chameaux (voir 1.3) doivent être utilisés pour séparer les mots d'un identifiant.

Raisonnement

Les noms d'identifiant lisibles sont très importants pour la maintenabilité. Limiter les identifiants à des conventions connues facilite également la transition entre différentes bases de code. Ces conventions particulières sont calquées sur les conventions standard du langage de programmation Java ™ [1] .

L'astuce

J'ai le regret d'informer l'équipe jQuery que le nom le plus courant pour leur "objet global jQuery" se heurte à cette convention de nom. Heureusement, ils ont déjà pensé à cela et fournissent les deux noms, $ainsi jQueryque des noms globaux faisant référence au même objet. J'imagine que le userbase pourrait ne pas être aussi envie de passer de $la jQuerypartout, cependant.

Luciole
la source
2
»Les fonctions doivent suivre les mêmes règles que le type d' identifiant « - voulez-vous dire »par le type de variable «?
Paŭlo Ebermann