Quarta-feira, Dezembro 30, 2009

Semiótica e Programação 3

Do ponto de vista do Java e do C#, C++ é uma linguagem fracamente tipada. Apesar de dizer isso abusar dos termos, existe um fundo de verdade ali.


C++, ao contrário de Java e C#, permite a formação de referências arbitrárias a qualquer objeto -- mesmo objetos hipotéticos.


Programas como este são aceitáveis, para o compilador:


list<string>* l = (list<string>*)0x12345;
l->sort();

Esta propriedade é inútil para a maioria dos programas, o que torna C++ excessivamente complicada aos olhos da maioria dos programadores. Se o programa está dizendo que naquele lugar ocorre um list<string> então isso deve ser verdade, certo? Boa sorte!

Existem programas que fazem uso dessa possibilidade, como programas para máquinas onde certos endereços são especiais e têm significado pré-definido.

Programas como este também são aceitáveis:

dog* marley = new dog();
spaceship* one = (spaceship*)marley;
one->launch();

Essa possibilidade é inerente à máquina, na medida em que o significante de uma referência existe apenas no mundo do discurso; a máquina conhece apenas bits. A reinterpretação de um padrão de bits é uma operação de pura semiótica: não é necessário computar nada, apenas compreender os bits de uma forma diferente. Assim sendo, C++ se limita a dizer que não fará esforço para garantir que esse programa faz sentido -- o problema é todo seu.

A estrutura que o tipo de uma referência impõe ao programa pode ser tal que nem todos os padrões de bits possíveis para aquele segmento de memória tenham um significado. Assim, apesar de o programa afirmar que ali está um objeto spaceship, o padrão de bits que ocorre ali pode não representar um objeto spaceship -- e o programa é literalmente um absurdo.

Em outras palavras, esse programa potencialmente viola invariantes do tipo spaceship, que são pré-condições automáticas para a chamada da função launch.

A reinterpretação irrestrita de objetos é uma das características mais estranhas dessa linguagem, e mais difícil de pôr em prática de forma útil.

Um desses usos é a transferência de objetos entre programas através de um dispositivo, técnica em que o programa receptor obtém uma pura sequência de bytes e assume que ali está o objeto transferido. Isso é chamado serialização porque torna o objeto, que possui significado e estrutura, em um série de bits.

Outro desses usos é a técnica de move construction do Elements of Programming, onde o objeto é reinterpretado de acordo com sua underlying class e copiado como tal -- e esta cópia é justamente a movimentação desejada.

0 comentários: