Jika Anda melihat ini, itu (hampir pasti) kesalahan pemrograman COBOL. Kebanyakan pemrogram COBOL membuat kesalahan bodoh ini, dan saya tidak terkecuali.
Masalahnya disebabkan oleh cara kami biasanya menginisialisasi rekaman. Mari kita ambil program kecil seperti ini:
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.
Dalam program ini, masukan catatan
dr-datarec. Biasanya ini berasal dari suatu tempat di disk, tetapi untuk pengujian sederhana ini dibuat secara manual.
Setelah record input diterima, komputasi dilakukan dan kemudian record tersebut dikeluarkan menggunakan
dt-detail.
Masalahnya adalah bagaimana record dibuat
dr-datarec. Perhatikan bagaimana spasi dipindahkan untuk memulainya. Ini adalah metode tipikal untuk menginisialisasi record.
Jadi, ada spasi di semua bidang PIC X. Tapi! Semua bidang COMP-3 juga diinisialisasi, tetapi tidak sampai nol. Pemrogram harus yakin bahwa nilai yang valid dihasilkan untuk semua bidang COMP-3. Program pengujian melakukannya dengan benar:
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
dr-amountJelas ada 100
di lapangan. Setelah dimulai ternyata:
./mistake
test 100.00
Bagaimana jika ada kesalahan encoding dan rekaman
dr-amounttidak diinisialisasi dengan benar?
Masih ada ruang ASCII di sana. Ini adalah nilai heksadesimal 20 atau biner 0010 0000.
COMP-3 menyimpan digit sebagai camilan empat-bit, jadi satu spasi ditampilkan sebagai 20. Jika Anda memiliki 9 digit seperti dr-jumlah, maka ini membutuhkan 10 camilan memori (9 camilan untuk digit dan satu untuk tanda) atau 5 byte.
Memindahkan spasi
dr-datarecakan menghasilkan 5 spasi atau nilai heksadesimal 2020202020 disimpan di bidang ini. Jika Anda mencoba menggunakan variabel yang tidak diinisialisasi, itu akan ditafsirkan sebagai 2020 202.02.
Jika Anda mengomentari inisialisasi
dr-amount, Anda dapat memaksakan kesalahan ini:
move spaces to dr-datarec.
move "test" to dr-name.
* move 100 to dr-amount.
Sekarang saat memulai program:
./mistake
test 2,020,202.02
Untuk memperbaiki masalah ini, COBOL 85 memperkenalkan kata kerja INITIALIZE. Alih-alih memindahkan spasi ke rekaman, Anda menginisialisasinya, dan ini akan memindahkan spasi ke bidang alfanumerik dan nol ke bidang numerik:
* move spaces to dr-datarec.
initialize dt-detail.
move "test" to dr-name.
* move 100 to dr-amount.
Hasil eksekusi:
./mistake
test 0.00
Jadi, lain kali Anda melihat seorang janda miskin yang mendapat tagihan listrik sebesar $ 2.020.202,02, Anda akan tahu persis apa yang terjadi!