Si ve esto, es (casi con seguridad) un error de programación COBOL. La mayoría de los programadores de COBOL cometen este estúpido error y yo no soy una excepción.
El problema se debe a la forma en que normalmente inicializamos el registro. Tomemos un pequeño programa como este:
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.
En este programa, el registro de entrada
dr-datarec
. Por lo general, proviene de algún lugar del disco, pero para esta simple prueba se crea manualmente.
Una vez que se recibe un registro de entrada, se realiza el cálculo y luego el registro se envía utilizando
dt-detail
.
El problema es cómo se crea el registro
dr-datarec
. Observe cómo se mueven los espacios para inicializarlo. Este era el método típico para inicializar un registro.
Por lo tanto, hay espacios en todos los campos PIC X. ¡Pero! Todos los campos COMP-3 también se inicializan, pero no a cero. El programador debe asegurarse de que se generen valores válidos para todos los campos COMP-3. El programa de prueba lo hace bien:
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
dr-amount
Claramente hay 100
en el campo. Después de comenzar, resulta:
./mistake
test 100.00
¿Qué pasa si hay un error de codificación y el registro
dr-amount
no se inicializa correctamente?
Todavía hay espacios ASCII allí. Este es un valor hexadecimal de 20 o binario 0010 0000.
COMP-3 almacena dígitos como nibbles de cuatro bits, por lo que un espacio se muestra como 20. Si tiene 9 dígitos como dr-amount, entonces esto requiere 10 nibbles de memoria (9 nibbles para dígitos y uno para signo) o 5 bytes.
Al mover espacios,
dr-datarec
se almacenarán 5 espacios o el valor hexadecimal 2020202020 en este campo. Si intenta utilizar una variable no inicializada, se interpretará como 2020202.02.
Si comenta la inicialización
dr-amount
, puede forzar este error:
move spaces to dr-datarec.
move "test" to dr-name.
* move 100 to dr-amount.
Ahora al iniciar el programa:
./mistake
test 2,020,202.02
Para solucionar este problema, COBOL 85 introdujo el verbo INICIALIZAR. En lugar de mover espacios a un registro, lo inicializa y moverá espacios a campos alfanuméricos y ceros a campos numéricos:
* move spaces to dr-datarec.
initialize dt-detail.
move "test" to dr-name.
* move 100 to dr-amount.
Resultado de ejecución:
./mistake
test 0.00
Entonces, la próxima vez que vea a una viuda pobre que recibió una factura de servicios públicos de $ 2,020,202.02, ¡sabrá exactamente qué sucedió!