Have an amazing solution built in RAD Studio? Let us know. Looking for discounts? Visit our Special Offers page!
Notícia

Problemas na combinação de objetos Classic e Clang: avisos do linker e melhoria da estabilidade do aplicativo

mixing-classic-and-clang-large-size-2

O vinculador C ++ Builder irá avisá-lo quando você misturar arquivos de objeto vinculados a clássico e clang, ajudando a evitar erros de vinculação ou de tempo de execução.

Hoje, em 2020, recomendamos o uso dos compiladores Clang modernos, especialmente com o trabalho que temos feito para Win64 (por exemplo, um depurador totalmente novo) e as melhorias de RTL para facilitar a atualização do clássico. No entanto, muitos clientes atualizam em etapas: primeiro do Win32 clássico para o Clang Win32 e, em seguida, adicionando o Win64. Na verdade, geralmente recomendamos isso diretamente como uma estratégia de atualização, para passar para o Clang primeiro e depois para o Win64, em duas etapas.

No entanto, há um problema comum ao passar dos compiladores clássicos para os compiladores clang. Os arquivos de objeto (bibliotecas .obj e .lib) gerados pelos compiladores clássicos e Clang Win32 não são binários compatíveis entre si. (Tanto o clássico quanto o clang podem se vincular ao Delphi, mas o clássico e o clang não podem se vincular.) Se você tentar construir um aplicativo em que algumas partes são construídas com o Clang e outras com o clássico, tudo misturado, você pode esperar qualquer coisa dos erros do vinculador à instabilidade do tempo de execução. Ainda assim, é fácil de fazer acidentalmente, tanto durante a atualização quanto apenas ao adicionar uma nova biblioteca ou EXE ao seu projeto.

Na versão 10.3.3, e isso foi documentado na ajuda online, mas não foi publicado no blog na época, adicionamos um novo aviso do linker para ajudá-lo a detectar essas situações.

Antes de mostrar a solução, vamos dar uma olhada rápida no que pode acontecer se você tiver esse erro em suas compilações.

Problemas quando compiladores incompatíveis

Na versão 10.3.3 e posteriores, você receberá um aviso do vinculador – veja abaixo – antes de qualquer um dos seguintes. Mas se você estiver usando uma versão mais antiga, antes de adicionarmos o aviso de diagnóstico do problema, você poderá ver apenas os erros a seguir. Eles aparecem ao vincular o aplicativo.

Erros de tempo de link

Quando um aplicativo criado com o conjunto de ferramentas Clang está vinculado a uma biblioteca clássica, você pode ver os seguintes erros:

Quando um aplicativo criado com o conjunto de ferramentas Classic é vinculado a uma biblioteca do Clang, você pode ver os seguintes erros:

Erros de tempo de execução

Em alguns casos, você pode não ver nenhum erro de vinculador e executará seu aplicativo. Provavelmente, em algum ponto, seu aplicativo irá travar e será difícil descobrir o porquê, porque o código parece bom. Na realidade, será devido a dois compiladores diferentes fazerem as coisas de maneiras diferentes – layout de memória diferente, alinhamento, expectativas de biblioteca de tempo de execução, tratamento de exceções, todos os tipos de diferenças possíveis.

Não é uma boa situação ter erros de linker estranhos ou comportamento de tempo de execução estranho. Então, adicionamos um aviso para verificar essa situação.

Diagnosticando: um Aviso de Novo Linker

RAD Studio / C ++ Builder 10.3.3 e mais recente avisa sobre a mistura de clang e clássico ao vincular. (Se ocorrerem erros do vinculador como o acima, este aviso é emitido antes deles, portanto, você verá o aviso antes de quaisquer erros devido ao problema.)

A mensagem diz ‘Aviso: incompatibilidade do compilador’. e depois diz o que esperava e o que encontrou:

Então, como o vinculador verifica se há objetos mistos e como ele sabe o que esperar?

No erro acima, eu tenho um aplicativo VCL vinculado a uma biblioteca estática. O aplicativo VCL é desenvolvido com Clang. A biblioteca é construída com clássicos. O aplicativo clang vincula-se à biblioteca com:

⸺ see documentation on linking with #pragma comment vs #link.

mixing-classic-and-clang-project-manager-1-2

É muito fácil cometer o erro de incompatibilidade de compiladores. Como você pode ver na captura de tela à direita, não é fácil dizer qual compilador Win32 está sendo usado. Isso é algo que poderíamos melhorar, mas agora ele lista a plataforma de destino, não o compilador.

Nosso compilador agora emite em cada objeto um registro (um pequeno pedaço de dados) dizendo com qual compilador ele foi construído (por exemplo, Clang Win32). Ao vincular, o vinculador recebe um conjunto de arquivos de objeto e bibliotecas, na ordem do comando linha. Ele olha para o primeiro objeto com o qual se vincula e marca que espera que todos os outros objetos sejam construídos com o mesmo compilador do primeiro. Para cada objeto que ele vincula (e dada uma biblioteca, que é apenas um conjunto de objetos, para cada objeto na biblioteca) ele verifica se foi construído com o compilador que está esperando.

mixing-classic-and-clang-1-2

Caso contrário, emite o aviso acima, que também pode ser visto na imagem à direita. Você pode ver que ele lista o objeto incorreto e com o que foi construído, e também explica por que estava procurando um compilador diferente. O objetivo é ajudá-lo a diagnosticar a configuração de sua compilação.

TLDR

Resumo rápido: misturar arquivos-objeto construídos com dois compiladores em um binário é uma má ideia. O vinculador lhe dará um aviso se você fizer isso, e lhe dirá o que foi construído com o que para que você possa corrigi-lo. Isso corrige problemas do vinculador e corrige problemas de estabilidade do aplicativo!

Leitura Adicional

Empacotando componentes ou bibliotecas escritas em compiladores Classic e Clang C ++ Win32
Esta nova página docwiki discute o aviso do vinculador, mas também contém um pouco mais de informações. Ele aborda como usar clang ou binários clássicos se você for um desenvolvedor de aplicativos e criar aplicativos com várias partes (talvez vinculando a uma biblioteca C ++ de código aberto que você também está criando) e também tem outra seção para se você for uma biblioteca desenvolvedor (por exemplo, escrever componentes ou bibliotecas e distribuí-los aos seus clientes).

Kai 1.1 Now Available! Kai 1.1 Now Available! What's Coming in RAD Studio 13.2 Florence

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.

Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

IN THE ARTICLES