| Bellacosa Mainframe e os ponteiros de memoria no COBOL Parte I |
COBOL Ponteiros de Memória: Os Cristais Kyber Escondidos do IBM Z
Parte 1 – O Despertar da Força dos Ponteiros
Quando o Padawan Descobre que um Endereço Pode Ser Mais Poderoso que os Dados
Por Bellacosa Mainframe
"O dado é importante. Mas conhecer onde ele vive na memória é conhecer a própria Força."
Mestre Sysprog Bellacosa
Introdução
Existe um momento na jornada de todo desenvolvedor COBOL em que ele acredita já ter visto praticamente tudo.
Aprendeu arquivos.
Aprendeu VSAM.
Aprendeu DB2.
Aprendeu CICS.
Aprendeu tabelas OCCURS.
Aprendeu REDEFINES.
Aprendeu recursão.
Aprendeu programas aninhados.
Aprendeu até THREADSAFE.
Então um dia aparece um código semelhante a este:
01 PTR-CLIENTE USAGE POINTER.
SET PTR-CLIENTE TO ADDRESS OF WS-CLIENTE.
O jovem Padawan olha para aquilo e pergunta:
Mestre…
COBOL tem ponteiros?
O mestre sorri.
Toma um gole de café.
E responde:
Sim.
E são provavelmente uma das funcionalidades menos conhecidas, mais poderosas e potencialmente mais perigosas disponíveis no IBM Enterprise COBOL.
O grande mito
Existe um mito muito comum.
"COBOL não trabalha com endereços."
Errado.
COBOL trabalha.
Sempre trabalhou.
Só que de forma extremamente controlada.
Enquanto linguagens como C permitem brincar livremente com memória:
int *p;
COBOL diz:
Jovem Padawan...
Se você vai manipular memória...
Faça isso com respeito.
O que é um ponteiro?
Um ponteiro não é um dado.
Ele não contém um nome.
Ele não contém um CPF.
Ele não contém uma data.
Ele contém:
O endereço onde algo está.
Imagine.
Apartamento:
Rua Jedi 500
Apartamento 1001
O apartamento é o dado.
O endereço é o ponteiro.
Exemplo.
Cliente
Nome
Bellacosa
Está armazenado em:
7FFF012345678
O ponteiro guarda:
7FFF012345678
Nada mais.
Por que isso existe?
Porque às vezes queremos acessar memória dinamicamente.
Criar estruturas.
Buffers.
Caches.
Árvores.
Filas.
Listas.
Comunicar com C.
Trabalhar com APIs.
Manipular XML.
Shared Memory.
LE Runtime.
COBOL sempre teve ponteiros?
Não.
COBOL 60
Não.
COBOL 68
Não.
COBOL 74
Não.
A situação começou a mudar com:
COBOL 85
Mais tarde.
IBM Enterprise COBOL.
Introduziu:
USAGE POINTER
ADDRESS OF
BASED
ALLOCATE
FREE
Atualmente.
Enterprise COBOL
4
5
6
6.3
6.4
6.5
Suportam totalmente.
O que é USAGE POINTER?
É o tipo especial que armazena um endereço.
Exemplo.
01 WS-PTR.
USAGE POINTER.
ou
01 WS-PTR POINTER.
Não faça:
PIC X(08)
Errado.
Não faça:
PIC 9(18)
Errado.
O compilador conhece o formato.
Você não precisa.
ADDRESS OF
Talvez seja a instrução mais importante.
Exemplo.
Temos.
01 WS-CLIENTE.
05 WS-NOME PIC X(30).
Pegando endereço.
SET WS-PTR
TO ADDRESS OF WS-CLIENTE
Pronto.
Agora.
WS-PTR aponta.
Para WS-CLIENTE.
Visualmente
Antes.
WS-PTR
NULL
Depois.
WS-PTR
0000007FFF123450
Como funciona na memória
Imagine.
Working Storage
ENDEREÇO
1000
WS-NOME
Bellacosa
1030
WS-IDADE
52
1035
WS-PTR
Executamos.
SET PTR
TO ADDRESS OF WS-NOME
Resultado.
PTR
1000
O ponteiro virou.
Uma espécie de GPS.
O que é SET?
SET é o comando utilizado.
Para manipular ponteiros.
Exemplo.
SET PTR
TO ADDRESS OF WS-DADOS
Outro.
SET PTR TO NULL
Muito importante.
Sempre inicializar.
Boa prática.
SET PTR TO NULL
No início.
Primeiro exemplo completo
Passo 1
Criar estrutura
WORKING-STORAGE SECTION.
01 WS-CLIENTE.
05 WS-NOME.
PIC X(30).
01 WS-PTR
USAGE POINTER.
Passo 2
Preencher
MOVE 'BELLACOSA'
TO WS-NOME
Passo 3
Capturar endereço
SET WS-PTR
TO ADDRESS OF WS-CLIENTE
Passo 4
Display
DISPLAY 'PONTEIRO OK'
Fim.
O que o compilador faz?
Compilador cria.
Variável especial.
Compatível com arquitetura.
31 bits.
64 bits.
Padawan pergunta.
Mestre...
Então é um hexadecimal?
Resposta.
Sim.
Normalmente.
Exemplo.
0000000012345678
IBM Z e endereçamento
Aqui começa a magia.
IBM Z possui longa história.
AMODE 24
Década 70.
Memória.
16 MB.
AMODE 31
1983
2 GB
AMODE 64
zSeries
Exabytes teóricos.
COBOL acompanha.
Working Storage
Ponteiros podem apontar para:
Working Storage
Local Storage
Heap
Dynamically allocated
LE Areas
Buffers
Stack
Existe outra área.
Stack.
Exemplo.
Função chamada.
STACK
Frame A
Frame B
Frame C
Cada frame.
Possui.
Variáveis.
Retorno.
Contexto.
Ponteiros podem apontar.
Para stack.
Sim.
Mas aqui mora perigo.
O lado sombrio
Imagine.
Procedimento.
Termina.
Stack destruída.
Ponteiro ainda existe.
Aponta.
Para memória inválida.
Chamamos isso.
Dangling Pointer.
Exemplo.
PTR
12345
Memória já morreu.
Resultado.
SOC4.
Heap
Heap é diferente.
Sobrevive.
Mais tempo.
Usado em.
ALLOCATE.
CEEGTST.
GETMAIN.
Mais seguro.
Curiosidade
Muitos programas COBOL bancários.
Nunca usam ponteiros.
Por quê?
Não precisam.
COBOL nasceu.
Para registros.
Arquivos.
Campos fixos.
Ponteiros vieram.
Muito depois.
Vantagens
Extremamente rápidas.
Não copia dados.
Exemplo.
Mover.
1 MB.
Custa.
CPU.
Mover ponteiro.
8 bytes.
Instantâneo.
Onde usar?
Excelente para.
XML
JSON
Árvores
Cache
Filas
MQ
Buffers
APIs
Sockets
C
Metal C
Onde NÃO usar?
Cadastro clientes.
Folha pagamento.
Relatórios.
VSAM simples.
Batch convencional.
Performance
Muito boa.
Quase zero overhead.
Mas.
Erro custa caro.
Um MOVE errado.
Perde registro.
Ponteiro errado.
Pode derrubar programa.
SOC4.
Segurança
Ponteiros são ferramenta poderosa.
Mas perigosos.
Podem causar.
Corrupção memória.
Exposição dados.
Abends.
Memory leaks.
Padawan deve lembrar.
Ponteiro não sabe.
Se memória ainda existe.
Ele apenas acredita.
Curiosidades Bellacosa
Pouquíssimos desenvolvedores COBOL escrevem código com ponteiros diariamente.
Mas os profissionais que trabalham com:
Language Environment
XML parsers
CEEGTST
Metal C
DB2 internals
Middleware
MQ exits
CICS User Exits
z/OS Connect
Parsers de alta performance
frequentemente encontram USAGE POINTER, ADDRESS OF, BASED e estruturas dinâmicas escondidas em programas aparentemente inocentes.
O Conselho do Mestre Bellacosa
Imagine que os dados COBOL são sabres de luz.
Você pode segurá-los diretamente.
Pode copiá-los.
Pode movê-los.
Pode validá-los.
Mas um ponteiro é diferente.
Um ponteiro é um mapa para encontrar o sabre.
Ele não contém energia.
Ele não contém plasma.
Ele apenas diz:
"Vá até aquele lugar da memória e você encontrará aquilo que procura."
E essa é justamente a beleza e o perigo dos ponteiros em COBOL.
Eles permitem que o Padawan transcenda a programação tradicional baseada em registros fixos e passe a manipular a própria estrutura da memória do IBM Z.
Mas também ensinam uma das maiores lições do universo mainframe:
O dado pode estar protegido por RACF.
O dataset pode estar catalogado.
O programa pode ser RENT e THREADSAFE.
Mas um ponteiro errado continua tendo o poder de levar até mesmo um Mestre Sysprog ao temido S0C4.
Continua na Parte 2 – BASED, ALLOCATE, CEEGTST e Estruturas Dinâmicas: Construindo Listas Encadeadas no IBM Z.
Sem comentários:
Enviar um comentário