Nível 77: Herança do passado ou boa prática?

Nível 77: Herança do passado?
Photo by Ann H on Pexels

Se você trabalha ou já trabalhou com COBOL com certeza já se deparou com variáveis definidas como nível 77. E você já se perguntou por que elas foram criadas dessa forma?

O que é?

O nível 77 é usado para definir itens elementares, que não pertencem a nenhum item de grupo.

Por exemplo, se seu programa precisa de um contador de linhas impressas, você poderia declará-lo assim:

77 WT-CT-LINHAS PIC 9(003) VALUE ZEROS.

…ao invés de…

01 WT-CT-LINHAS PIC 9(003) VALUE ZEROS.

Quando a gente começa a trabalhar com sistemas legados e encontra uma sequência de variáveis no nível 77 que poderiam perfeitamente estar no nível 01 ou 03, a primeira coisa que passa pela cabeça é que deve existir alguma razão de arquitetura para que seja assim.

E realmente existe. Ou melhor, existiu.

“Fronteiras de memória”

Nos primeiros mainframes, especialmente depois do IBM System/360, memória RAM era artigo de luxo, processadores não eram tão “espertos” e, consequentemente, compiladores não podiam otimizar muita coisa.

Para um programa ser rápido, as variáveis precisavam estar alinhadas perfeitamente em palavras de 4 ou 8 bytes (as chamadas word boundaries).

Se um dado estivesse desalinhado, o hardware precisava de dois ciclos de leitura em vez de um para localizá-lo na memória quando precisasse. Em processamentos de milhões de registros, isso fazia muita diferença.

E o nível 77 era um “atalho” para otimização de performance.

Quando o programador declarava um item como nível 77, ele estava dando uma ordem clara ao compilador: “Isole esta variável! Ela não faz parte de nenhum item de grupo e, por isso, deve começar no início de uma fronteira de memória.”

Com isso, contadores, acumuladores, flags… tudo o que seria intensivamente usado pelo programa, estaria posicionado em memória para ser localizado mais rapidamente do que outros itens elementares criados como nível 03, 05 ou 07 de um item de grupo, que exigiriam cálculos adicionais de offset.

Por que isso virou “coisa do passado”?

Com a evolução da arquitetura dos mainframes, até chegar à IBM z/Architecture e aos compiladores IBM Enterprise COBOL, essa necessidade morreu por dois motivos:

1) Os compiladores ficaram mais inteligentes: Hoje, o compilador organiza os níveis 01 de forma tão eficiente que ele mesmo insere “espaços vazios” (slack bytes) para garantir o alinhamento sem que você precise pedir.

2) O hardware ficou mais poderoso: Os processadores atuais lidam com cálculos de offset de forma quase instantânea. A diferença de microssegundos que o nível 77 economizava simplesmente deixou de existir.

Então devo usar ou não?

Em código novo, sim, vai de nível 01.

Ou melhor ainda, organize seu itens elementares em itens de grupo (flags, contadores, acumuladores etc.) e coloque o item elementar como nível 03 no item de grupo correspondente. A working-storage fica mais organizada e fácil de entender.

Em código legado, se o programa que você está alterando já usa 77, mantenha a consistência. A regra de ouro da manutenção é: não quebre o padrão visual do que já funciona, pois isso ajuda o sistema a continuar rodando por mais algumas décadas.