Si vous voyez cela, c'est (presque certainement) une erreur de programmation COBOL. La plupart des programmeurs COBOL font cette stupide erreur, et je ne fais pas exception.
Le problème est causé par la façon dont nous initialisons habituellement l'enregistrement. Prenons un petit programme comme celui-ci:
identification division.
program-id.
mistake.
data division.
working-storage section.
* *** Input record, typically maintained on disk/tape somewhere.
01 dr-datarec.
03 dr-name pic x(20).
03 dr-amount pic s9(7)v99, comp-3.
* *** print record, sent to a line printer.
01 dt-detail.
03 dt-name pic x(20).
03 filler pic x.
03 dt-amount pic z,zzz,zz9.99.
procedure division.
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
move spaces to dt-detail.
move dr-name to dt-name.
move dr-amount to dt-amount.
display dt-detail.
stop run.
Dans ce programme, l'enregistrement d'entrée
dr-datarec
. Habituellement, il vient de quelque part sur le disque, mais pour ce test simple, il est créé manuellement.
Une fois qu'un enregistrement d'entrée est reçu, le calcul est effectué, puis l'enregistrement est sorti en utilisant
dt-detail
.
Le problème est de savoir comment l'enregistrement est créé
dr-datarec
. Remarquez comment les espaces sont déplacés pour l'initialiser. C'était la méthode typique pour initialiser un enregistrement.
Ainsi, il y a des espaces dans tous les champs PIC X. Mais! Tous les champs COMP-3 sont également initialisés, mais pas à zéro. Le programmeur doit s'assurer que des valeurs valides sont générées pour tous les champs COMP-3. Le programme de test le fait correctement:
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
Il y en a
dr-amount
clairement 100 sur le terrain. Après le démarrage, il s'avère:
./mistake
test 100.00
Que faire s'il y a une erreur de codage et que l'enregistrement n'est
dr-amount
pas initialisé correctement?
Il y a encore des espaces ASCII là-dedans. Il s'agit d'une valeur hexadécimale de 20 ou binaire 0010 0000.
COMP-3 stocke les chiffres sous forme de quartets de quatre bits, donc un espace est affiché comme 20. Si vous avez 9 chiffres comme dr-amount, cela nécessite 10 grignotages de mémoire (9 quartets pour les chiffres et un pour le signe) ou 5 octets.
Le déplacement d'espaces dans
dr-datarec
entraînera le stockage de 5 espaces ou de la valeur hexadécimale 2020202020 dans ce champ. Si vous essayez d'utiliser une variable non initialisée, elle sera interprétée comme 2020 202.02.
Si vous commentez l'initialisation
dr-amount
, vous pouvez forcer cette erreur:
move spaces to dr-datarec.
move "test" to dr-name.
* move 100 to dr-amount.
Maintenant, au démarrage du programme:
./mistake
test 2,020,202.02
Pour corriger ce problème, COBOL 85 a introduit le verbe INITIALIZE. Au lieu de déplacer des espaces vers un enregistrement, vous l'initialisez et il déplacera les espaces vers les champs alphanumériques et les zéros vers les champs numériques:
* move spaces to dr-datarec.
initialize dt-detail.
move "test" to dr-name.
* move 100 to dr-amount.
Résultat de l'exécution:
./mistake
test 0.00
Ainsi, la prochaine fois que vous verrez une pauvre veuve qui a reçu une facture de services publics de 2 020 202,02 $, vous saurez exactement ce qui s'est passé!