Ponteiros
Aritmética por elemento, cast, distância — e as duas formas de um ponteiro não valer nada.
Andar por elemento, e não por byte#
p := Est.ponteiro(numeros, "u32")
out p.ler()
out p.mais(1).ler() // o PRÓXIMO u32
out p.mais(1).endereco() // 4 — e não 1
out p.cluster(4) // os quatro a partir daquip + 1 num u32* do C anda quatro bytes. Andar um byte é um índice, não um ponteiro — e é a conta que quem escreve C faz o tempo todo. p.distancia(q) responde na mesma unidade, e é recusada entre tipos diferentes: a conta é em elementos, e dois tipos têm tamanhos diferentes.
O cast#
p.como("u8").mais(3).ler() // os mesmos bytes, outro tipoAs duas formas de não valer nada#
| O que é | |
|---|---|
Est.nulo() | o endereço existe e vale zero; lê-lo seria a falha de segmentação clássica |
| bloco liberado | o endereço continua na mão de alguém, e o bloco declarou o fim |
p := Est.nulo()
out p.e_nulo() // yes
p.ler() // NullPointerError
morto := Est.bloco(8)
q := Est.ponteiro(morto, "u32")
morto.liberar()
q.ler() // DanglingPointerErrorNullPointerError é diferente de NullReferenceError, que fala de um void da linguagem. Aqui o endereço existe.
O ponteiro segura o bloco — e isso é uma decisão#
União#
Valor := Est.uniao("Valor", [
["inteiro", "u32"],
["flutuante", "f32"]
], ordem := "rede")
Valor.escrever(caixa, {"flutuante": 1.0})
out Valor.ler(caixa)["inteiro"] // 1065353216 — o IEEE 754 de 1.0Todos os campos no mesmo deslocamento zero, e o tamanho é o do maior. Escrever um e ler outro devolve a reinterpretação dos bytes — que é o ponto de uma união, e também o que a torna perigosa quando o tipo escrito não é registrado em algum lugar.
O exemplo completo#
examples/estrutura_binaria.df monta um arquivo com cabeçalho e três registros, percorre com janelas, escreve por ponteiro e demonstra as cinco recusas — com assert em cada afirmação.