transborda em adições size_t
-
03-07-2019 - |
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
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 exigesize_t
sempre ser um tipo não assinado. Para compatibilidade com sistemas existentes arquivos de cabeçalho, GCC definesize_t
emstddef.h
para ser o que digite osys/types.h
do sistema define a estar. A maioria dos sistemas Unix que definemsize_t
emsys/types.h
, definem a ser um tipo assinado. Algum código no biblioteca dependesize_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 desize_t
como um tipo assinado está incorreto. Pretendemos que na versão 2,4, GCC irá sempre definirsize_t
como um tipo sem sinal, e o script 'fixincludes' vai massagear osys/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 parasize_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.