Segunda-feira, Novembro 23, 2009

Mais sombras no Ambiente de Programação C++

Estou lendo a ementa do curso de pós-graduação em Análise e Projeto de Sistemas da PUC-Rio, onde ocorre o seguinte:

"Laboratório de Linguagens de Programação

Objetivo – Capacitar o aluno a distinguir os principais componentes de linguagens de programação não convencionais tais como: programação orientada a objetos, programação orientada a eventos e programação para Internet/intranet."

A presença de "programação orientada a eventos" ali é interessante; a ementa prossegue em explicar que neste módulo o aluno aprenderá a programar Applets Java, que são orientados a eventos.

O que se chama "orientação a eventos" ali é uma técnica de projeto de aplicativos úteis plugados em algum tipo de framework de apoio, que cuida de enviar os tais eventos para o aplicativo.

Há um sub-grupo dos programadores de C++ que dirá a você que "não programa interfaces de usuário". Essa é uma afirmação interessante porque, compreendido com rigor máximo, significa que os programas produzidos por essa pessoa produzem resultados totalmente invisíveis.

Todo programa de computador possui uma interface de usuário -- senão, o usuário nunca veria seu resultado. Programadores C++ são criados desde o berço para produzir programas cuja interface com o usuário é o terminal -- um dispositivo capaz de apresentar um mapa de 80x24 caracteres.

O que há de interessante nisso é que existe um mecanismo subjacente a esse terminal que suporta a parafernália usada para pôr ali os tais caracteres -- std::cout, printf etc. Esse mecanismo é inicializado, mantido e finalizado pela implementação do C++ de forma oculta ao usuário.

Existem ambientes peculiares onde o C++ não inicializa nada disso -- ou inicializa essas coisas de forma inesperada. Os compiladores da Microsoft oferecem um parâmetro de chamada ao compilador para selecionar o "subsistema" -- CONSOLE ou WINDOWS. Aplicativos compilados para o subsistema WINDOWS não fazem coisas úteis quando o programa chama printf.

No projeto onde estou alocado agora, o sistema implantado no dispositivo-alvo é altamente customizado, e a biblioteca padrão C++ apresenta esquisitices parecidas. Não existe um "terminal" e chamar printf às vezes não faz nada, às vezes bloquea o sistema eternamente em um signal handler.

Bibliotecas como a Qt e a Glib oferecem uma terceira via, que talvez pudesse ser compreendida como um terceiro subsistema, o EVENT_LOOP. Esse subsistema possui sua própria API e faz tudo pela aplicação, que apenas inicia operações no sistema e senta esperando por notificações sobre o resultado. Assim são os Applets Java.

Tudo isso sugere que o ambiente de execução do C++ executa mais que apenas o código da aplicação, e de fato existem atividades que ocorrem antes de main iniciar e depois de main finalizar. O programador atento procurará pelo código-fonte ou executável do CRT no seu sistema -- o C Run-Time.

7 comentários:

ricbit disse...

As pessoas que usam C++ em backends e serviços de infraestrutura realmente não programam nada de interface de usuário.

Caloni disse...

Exatamente. Levado ao extremo, a frase "Todo programa de computador possui uma interface de usuário" não leva em conta os milhões de microcontroladores, drivers e serviços de diversos sistemas operacionais, incluindo muitas partes desses sistemas. Um dos motivos, aliás, da criação da linguagem (C).

P. disse...

Acompanhando vocês, um programador que sempre implementou funções livres, nunca um sistema inteiro, também nunca programou para uma interface de usuário.

Porém, se ele programou em Python, alguém pode argumentar que isso não é verdade, porque um interpretador como o IDLE permite ao usuário chamar funções livres à vontade -- para teste, ou sei lá.

Todo programa se comunica com um usuário -- quer dizer, todo programa troca dados com o mundo além da máquina onde ele roda.

É interessante ver pessoas usando aparelhos engraçados como JTAGs para se tornar "usuário" de programas entalados nas profundezas -- ou gente de kernel em sessões de debugging.

ricbit disse...

Mas aí você está mudando a definição de usuário, e pela lei de ricbit a thread acabou.

Caloni disse...

Discordo. Essa nova noção de "interface" e "usuário" tornaram mais rica a definição, apesar de ser uma forma um tanto ambígua de dizer que "todo programa possui uma forma de comunicação com o mundo externo", onde "forma de comunicação" e "mundo externo" fazem os papéis mais genéricos de "interface" e "usuário".

Talvez não tivesse sido essa a intenção no artigo original, mas enfim, é para isso que os comentários estão abertos, não é mesmo? =)

[]s

P. disse...

Com certeza essa discussão esticou bastante o meu tema original.

Se nós vamos entrar bem fundo na máquina, eu só posso falar em "usuário" usando alguma noção bem abstrata de "observação".

Daí, diria que todo programa útil precisa ter efeitos observáveis -- por um "usuário" humano ou animal, porque os objetos inanimados não usam os computadores.

A conclusão seria então que, transversalmente ao problema matemático resolvido por um programa, existe sempre o problema de comunicar o resultado da computação de alguma forma.

De fato, na especificação do C, um programa é definido pelos "efeitos observáveis" que provoca na máquina abstrata.

E bla, bla, bla...

Anônimo disse...

Procure por C++Builder meu caro total RAD.