Pergunta

No momento, estou trabalhando na conversão de um aplicativo de 32bits em um aplicativo de 64bits em C. Esta aplicação está atualmente trabalhando em arquitetura x86 (Windows, OSX, Unix, Linux). Então, antes de iniciar a codificação, eu queria saber o que eu preciso considerar ao converter o aplicativo.

Foi útil?

Solução

  1. Descubra quem a escreveu. Eles são um idiota? Eles são você de alguns anos atrás? Pode perguntar-lhes perguntas? Eles estão familiarizados com a existência de múltiplas plataformas e sistemas? Sabendo a mentalidade do autor (s) do programa irá ajudá-lo a compreender os problemas quando você correr para eles.
  2. Obter um ambiente de máquina / build de 64 bits instalado e funcionando.
  3. Substitua por muito tempo com int. Estar perfeitamente ciente de que LONG não é long.
  4. Substitua (int)&x moldes e digitação com intptr_t e (unsigned int)&x com uintptr_t
  5. Auditoria qualquer coisa que se baseia em lançar estruturas para char* para fazer aritmética de ponteiro com ele.
  6. Pesquisa Regex para \ <4 \> no caso de você assumiu 4 = sizeof(void*)
  7. Seja paciente. Quando você encontrar um problema, procure outro lugar se o mesmo problema existe, e enrole a solução em um macro.
  8. Tente não usar #ifdef RUN64 ou qualquer coisa semelhante. Você vai se arrepender se plataformas 128 bits nunca entrar em voga.
  9. Encapsulate todas as suas alterações em termos de alguns macros centralizado que vai esconder as diferenças de portabilidade em outros lugares em seu programa.
  10. Use um testador de cobertura para ajudar a garantir que você cobriu tudo (se for o caso)

Editar nota uintptr_t adicionado como sugerido pelo comentário.

Outras dicas

Um problema potencial não já mencionado é que, se seu aplicativo lê ou grava dados binários de disco (por exemplo, ler um conjunto de estruturas que utilizam fread), você vai ter que verificar com muito cuidado e, talvez, acabam tendo dois leitores: um para arquivos de legado e um para arquivos de 64 bits. Ou, se você for cuidadoso para usar tipos como uint32_t e assim por diante a partir do arquivo de cabeçalho <stdint.h>, você pode redefinir suas estruturas para ser bit-por-bit compatível. Em qualquer caso, I binário / O é uma coisa que atente para.

Isso realmente depende da aplicação e como ele foi codificado. Algum código pode apenas ser recompilados com um compilador de 64 bits e ele vai funcionar, mas geralmente isso só acontece se o código foi projetado com portabilidade em mente.

Se o código tem um monte de suposições sobre o tamanho dos tipos nativos e ponteiros, se ele tem um monte de hacks pouco de embalagem ou de fala de um processo externo usando um protocolo byte especificado, mas utilizando algumas suposições sobre o tamanho de tipos nativos em seguida, ele pode exigir alguma, ou muito, de trabalho para obter uma compilação limpa.

Praticamente todos os aviso elenco e compilador é uma bandeira vermelha que precisa conferir. Se o código não era "aviso limpa" para começar, então, que é também um sinal de que pode ser necessário um monte de trabalho.

Se você usou os tipos corretos para os seus valores - por exemplo. size_t, ptrdiff_t, uintptr_t, os tipos int tamanho fixo de stdint.h se for o caso -. e não tamanhos valor codificar, seu código deve funcionar fora da caixa

O principal problema que enfrentamos ao mudar para 64 bits é que o tamanho dos ponteiros são diferentes (64 bits em vez de 32 - duh). O tamanho de inteiros eo tamanho do longs podem diferir muito, dependendo da plataforma

Porque é que este problema um? Bem, não é, a menos que seu código assume que sizeof (int) == sizeof (* void). Isto pode levar a erros de ponteiro desagradáveis.

Bem, fundamentalmente, o número de mudanças são relativamente pequeno, mas que ainda vai ser uma tarefa importante se o aplicativo não é cuidadosamente escrito para ser um pouco portátil para começar.

A principal diferença é que os ponteiros são 64 bits de largura, e a maioria dos outros tipos de dados mantêm-se inalterados. Um int ainda é de 32 bits, e uma longa é provavelmente também ainda de 32 bits. Portanto, se seus moldes de código entre inteiros e ponteiros, que vai quebrar. Da mesma forma, qualquer estrutura ou semelhante, que depende de um deslocamento para um membro específico pode quebrar porque os outros membros podem agora ser maior, e assim mudar o offset.

É claro, seu código nunca deve contar com esses truques, em primeiro lugar, de modo que em um mundo ideal, isso não seria um problema de todos, e você poderia simplesmente recompilação e tudo iria funcionar. Mas você provavelmente não vivemos em um mundo ideal ...;)

As duas diferenças principais entre 32 bits e 64 bits de programação em C são sizeof (void *) e sizeof (longo). O grande problema que você terá é que a maioria dos sistemas Unix utilizam o padrão I32LP64 que define um longo como 64 bits e Win64 usa o padrão IL32LLP64 que define um longo como 32 bits. Se você precisa para apoiar a compilação multi-plataforma, você pode querer usar um conjunto de arquitetura baseada typedefs para inteiros de 32 bits e 64 bits para garantir que todo o código irá se comportar de forma consistente. Este é fornecido como parte de stdint.h como parte da norma C99. Se você não estiver usando um compilador C99, você pode precisar rolar o seu próprio equivalente

Como observado em outros lugares as principais preocupações para a conversão será código que assumir sizeof (int) == sizeof (long) == sizeof (void *), código de dados de suporte que tenha sido gravados no disco e código para plataformas IPC .

Para uma boa revisão da história por trás disso, dê uma olhada neste artigo partir de ACM Queue.

Existem muitas boas respostas já.

Considere o uso Gimpel Lint . Ele pode apontar exatamente os tipos de construções que são problemáticos. Se a sua experiência é como o meu, que também irá mostrar-lhe lotes de bugs no sistema não relacionados à porta 32/64 bit.

Todos os cerca de 64-bit para os desenvolvedores:

Artigos sobre Desenvolvimento de 64 bits

de 64 bits Recursos

Viva64

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top