Wenn Sie dies sehen, handelt es sich (mit ziemlicher Sicherheit) um einen COBOL-Programmierfehler. Die meisten COBOL-Programmierer machen diesen dummen Fehler, und ich bin keine Ausnahme.
Das Problem wird durch die Art und Weise verursacht, wie wir den Datensatz normalerweise initialisieren. Nehmen wir ein kleines Programm wie dieses:
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.
In diesem Programm der Eingabedatensatz
dr-datarec
. Normalerweise kommt es von irgendwo auf der Festplatte, aber für diesen einfachen Test wird es manuell erstellt.
Sobald ein Eingabedatensatz empfangen wurde, wird die Berechnung durchgeführt und dann wird der Datensatz mit ausgegeben
dt-detail
.
Das Problem ist, wie der Datensatz erstellt wird
dr-datarec
. Beachten Sie, wie die Leerzeichen verschoben werden, um sie zu initialisieren. Dies war die typische Methode zum Initialisieren eines Datensatzes.
Somit gibt es in allen Bereichen von PIC X Leerzeichen. Aber! Alle COMP-3-Felder werden ebenfalls initialisiert, jedoch nicht auf Null. Der Programmierer muss sicherstellen, dass für alle COMP-3-Felder gültige Werte generiert werden. Das Testprogramm macht es richtig:
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
Es sind
dr-amount
eindeutig 100 auf dem Feld. Nach dem Start stellt sich heraus:
./mistake
test 100.00
Was ist, wenn ein Codierungsfehler vorliegt und der Datensatz
dr-amount
nicht ordnungsgemäß initialisiert wurde?
Es gibt dort noch ASCII-Leerzeichen. Dies ist ein Hexadezimalwert von 20 oder binär 0010 0000.
COMP-3 speichert Ziffern als Vier-Bit-Halbbytes, sodass ein Leerzeichen als 20 angezeigt wird. Wenn Sie 9 Ziffern wie dr-Betrag haben, sind 10 Speicher-Halbbytes (9 Halbbytes) erforderlich für Ziffern und eine für Vorzeichen) oder 5 Bytes.
Das Verschieben von Leerzeichen
dr-datarec
führt dazu, dass 5 Leerzeichen oder der Hexadezimalwert 2020202020 in diesem Feld gespeichert werden. Wenn Sie versuchen, eine nicht initialisierte Variable zu verwenden, wird diese als 2020 202.02 interpretiert.
Wenn Sie die Initialisierung auskommentieren
dr-amount
, können Sie diesen Fehler erzwingen:
move spaces to dr-datarec.
move "test" to dr-name.
* move 100 to dr-amount.
Jetzt beim Starten des Programms:
./mistake
test 2,020,202.02
Um dieses Problem zu beheben, führte COBOL 85 das Verb INITIALIZE ein. Anstatt Leerzeichen in einen Datensatz zu verschieben, initialisieren Sie ihn und es werden Leerzeichen in alphanumerische Felder und Nullen in numerische Felder verschoben:
* move spaces to dr-datarec.
initialize dt-detail.
move "test" to dr-name.
* move 100 to dr-amount.
Ausführungsergebnis:
./mistake
test 0.00
Wenn Sie also das nächste Mal eine arme Witwe sehen, die eine Stromrechnung über 2.020.202,02 USD erhalten hat, wissen Sie genau, was passiert ist!