Pergunta

Eu gosto de ter o meu código de aviso livre para VS.NET e GCC, e eu gostaria de ter o meu código de 64 bits pronto.

Hoje eu escrevi um pequeno módulo que trata em buffers de memória e fornece acesso aos dados através de uma interface de estilo de arquivo (por exemplo, você pode ler bytes, bytes de gravação, procure em torno etc.).

Como o tipo de dados para a posição corrente de leitura e tamanho eu usei size_t desde que parece ser a escolha mais natural. I contornar as advertências e deveria trabalhar em 64 bits também.

Apenas no caso de: a minha estrutura esta aparência:

typedef struct
{
  unsigned char * m_Data;
  size_t          m_CurrentReadPosition;
  size_t          m_DataSize;
} MyMemoryFile;

A sinalização de size_t parece não ser definida na prática. code-uma pesquisa no Google provou isso.

Agora estou em um dilema: Quero verificar adições com size_t para estouros de porque eu tenho que lidar com dados fornecidos pelo usuário e bibliotecas de terceiros vão usar meu código. No entanto, para o transbordamento verificar Eu tenho que saber o sinal-ness. Faz uma diferença enorme na implementação.

Assim - como diabos eu deveria escrever esse código em uma plataforma e compilador forma independente?

Posso verificar a sinalização de size_t na corrida ou tempo de compilação? Isso resolveria o meu problema. Ou talvez size_t não era a melhor idéia em primeiro lugar.

Todas as idéias?

Editar : Eu estou procurando uma solução para a linguagem C

Foi útil?

Solução

Quanto ao se size_t é assinado ou não assinado e GCC (a partir de uma GCC antigo manual - Eu não tenho certeza se ele ainda está lá):

Há um problema potencial com o Tipo size_t e versões anteriores GCC para liberar 2.4. ANSI C que exige size_t sempre ser um tipo não assinado. Para compatibilidade com sistemas existentes arquivos de cabeçalho, GCC define size_t em stddef.h para ser o que digite o sys/types.h do sistema define a estar. A maioria dos sistemas Unix que definem size_t em sys/types.h, definem a ser um tipo assinado. Algum código no biblioteca depende size_t ser um tipo não assinado, e não vai funcionar corretamente se ele for assinado.

código da biblioteca GNU C que espera size_t como não assinado está correto. o definição de size_t como um tipo assinado está incorreto. Pretendemos que na versão 2,4, GCC irá sempre definir size_t como um tipo sem sinal, e o script 'fixincludes' vai massagear o sys/types.h do sistema de modo a não conflito com isso.

Enquanto isso, nós trabalhamos em torno deste problema, dizendo GCC explicitamente usar um tipo não assinado para size_t quando compilar a biblioteca GNU C. 'Configure' irá detectar automaticamente que usa o tipo do CCG para size_t organizar para substituí-lo se necessário.

Se você quiser uma versão assinada do uso size_t ptrdiff_t ou em alguns sistemas, há um typedef para ssize_t.

Outras dicas

size_t é um tipo integral sem sinal, de acordo com as normas C ++ C. Qualquer aplicação que tem size_t assinado está seriamente não-conformidade e, provavelmente, tem outros problemas de portabilidade também. É garantido para embrulhar em torno de quando transborda, o que significa que você pode escrever testes como if (a + b < a) para encontrar estouro.

size_t é um excelente tipo para qualquer coisa que envolva memória. Você está fazendo certo.

size_t deve ser assinado.

É tipicamente definido como unsigned long.

Eu nunca vi isso ser definido de outra forma. ssize_t é sua contraparte assinado.

EDIT: GCC define como assinado em algumas circunstâncias. compilar em modo ASNI C ou std-99 deve forçá-lo a ser assinado.

Para a linguagem C, o uso IntSafe . Também lançado pela Microsoft (que não deve ser confundido com o C ++ SafeInt biblioteca). IntSafe é um conjunto de chamadas de funções da linguagem C que podem executar matemática e fazer conversões com segurança. URL atualizados para funções intsafe

Use safeint . É uma classe desenhado por Michael Howard e lançado como open source da Microsoft. Ele é projetado para tornar o trabalho com números inteiros, onde estouro é identificado como um risco. Todos os excessos são convertidos para exceções e manipulados. A classe foi projetada para fazer uso correto fácil.

Por exemplo:

char CouldBlowUp(char a, char b, char c)
{
   SafeInt<char> sa(a), sb(b), sc(c);

   try
   {
     return (sa * sb + sc).Value();
   }
   catch(SafeIntException err)
   {
      ComplainLoudly(err.m_code);
   }

   return 0;
}

Além disso safeint é muito utilizada internamente na Microsoft em produtos como o Office.

Ref: texto do link

Eu não tenho certeza se eu entendi a pergunta exatamente, mas talvez você possa fazer algo como:

temp = value_to_be_added_to;

value_to_be_added_to += value_to_add;

if (temp > value_to_be_added_to)
{
  overflow...
}

Uma vez que vai envolver volta para valores mais baixos pode facilmente verificar se ele transbordou.

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