2008-10-15 17 views
6

Me gusta que mi código advierta de forma gratuita para VS.NET y GCC, y me gusta tener mi código listo para 64 bits.se desborda en size_t adiciones

Hoy escribí un pequeño módulo que trata con memorias intermedias de memoria y proporciona acceso a los datos a través de una interfaz de estilo de archivo (por ejemplo, puede leer bytes, escribir bytes, buscar, etc.).

Como el tipo de datos para la posición de lectura actual y el tamaño que utilicé size_t, ya que parece ser la elección más natural. Entiendo las advertencias y debería funcionar también en 64 bits.

Por si acaso: Mi estructura es similar a esto:

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

El signo numérico de size_t parece no estar definido en la práctica. Una búsqueda de código de Google demostró eso.

Ahora estoy en un dilema: quiero ver las adiciones con size_t para desbordamientos porque tengo que ocuparme de los datos proporcionados por el usuario y las bibliotecas de terceros utilizarán mi código. Sin embargo, para el control de desbordamiento, debo saber la firma. Hace una gran diferencia en la implementación.

Entonces, ¿cómo diablos debería escribir este código en una plataforma y el compilador de forma independiente?

¿Puedo verificar la firma de size_t en ejecución o en tiempo de compilación? Eso resolvería mi problema. O tal vez size_t no fue la mejor idea en primer lugar.

¿Alguna idea?

EDIT: ¡Estoy buscando una solución para el C-language!

+0

¿qué versión de gcc estás usando? Parece que hicieron size_t sin firmar en versiones posteriores e incluidas 2.4 –

+0

Las versiones con las que tengo que lidiar están por todos lados. Hago programación incrustada y a veces tengo que usar versiones de compilación de las edades de piedra. –

+0

"Signedness" es la palabra habitual. – Lassi

Respuesta

11

En cuanto a la si size _t es con o sin signo y GCC (de un viejo manual de GCC - No estoy seguro de si todavía está allí):

Hay un problema potencial con el tipo size_t y versiones de GCC anterior a la versión 2.4. ANSI C requiere que size_t sea siempre un tipo sin firmar. Para compatibilidad con archivos de cabecera sistemas existentes, GCC define size_t en stddef.h ser cualquier tipo de sistema sys/types.h define a ser . La mayoría de los sistemas Unix que definen size_t en sys/types.h, defínanlo a sea un tipo firmado. Cierto código en la biblioteca depende de size_t siendo un tipo sin signo , y no funcionará correctamente si está firmado.

El código de la biblioteca GNU C que espera que size_t sea unsigned es correcto. La definición de size_t como tipo firmado es incorrecta. Tenemos la intención de que en la versión 2.4, GCC siempre se definirá size_t como un tipo sin signo, y el guión los '' fixincludes a masajear conflicto sys/types.h a fin de no del sistema con esto.

Mientras tanto, nos evitar este problema diciendo GCC explícitamente a utilizar un tipo sin signo de size_t cuando la compilación de la biblioteca de C de GNU. 'configure' detectará automáticamente qué tipo utiliza GCC para size_t arregle para anularlo si es necesario.

Si desea una versión firmada de size_t uso ptrdiff_t o en algunos casos existe un typedef para ssize_t.

+1

wow! muchas gracias por excavar para la historia del problema –

+2

Tuve que hacerlo por mi propia curiosidad: me resultaba difícil creer que GCC ignoraría una parte bastante básica del estándar sin una explicación decente. –

4

size_t debe estar sin firmar.

Se define normalmente como sin signo de longitud.

Nunca he visto que se defina lo contrario. ssize_t es su contraparte firmada.

EDITAR: GCC lo define como firmado en algunas circunstancias. compilar en modo ASNI C o std-99 debería forzar que no esté firmado.

+0

GCC define size_t como firmado :( –

+0

No tiene unsigned long 32 bits en ventanas de 64 bits? No es una buena suposición para size_t. – ejgottl

+0

g ++ 4.2.3 lo define como unsigned. – ejgottl

0

Use safeint. Es una clase diseñada por Michael Howard y lanzada como fuente abierta de Microsoft. Está diseñado para trabajar con enteros donde el desbordamiento se identifica como un riesgo. Todos los desbordamientos se convierten en excepciones y se manejan. La clase está diseñada para facilitar el uso correcto.

Por ejemplo:

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; 
} 

también safeint se utiliza mucho internamente en Microsoft en productos como Office.

Ref: link text

+0

No puedo usar SaveInt. Soy C-only, y afaik saveint no resuelve el problema de firma también porque asume los valores predeterminados de msvc. –

+0

Oh, la pregunta se marcó inicialmente como C++. Consulte mi otra respuesta para una biblioteca de lenguaje C. –

+0

Sí, lo sé. Disculpe. He editado la pregunta para asegurarme de no engañar alguien más. –

0

No estoy seguro si entiendo la pregunta exactamente, pero tal vez usted puede hacer algo como:

temp = value_to_be_added_to; 

value_to_be_added_to += value_to_add; 

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

Ya que envolverá de nuevo a los valores más bajos se puede comprobar fácilmente si se desbordó.

+0

¿Qué pasa si value_to_add es negativo? –

+0

Verifique lo contrario. –

2

Para el lenguaje C, use IntSafe. También lanzado por Microsoft (no debe confundirse con la biblioteca C++ SafeInt). IntSafe es un conjunto de llamadas a función de lenguaje C que pueden realizar operaciones matemáticas y realizar conversiones de forma segura. updated URL for intsafe functions

4

size_t es un tipo integral sin signo, de acuerdo con los estándares C++ C. Cualquier implementación que tenga size_t firmado es seriamente no conforme, y probablemente también tenga otros problemas de portabilidad. Está garantizado para envolverse cuando se desborda, lo que significa que puede escribir pruebas como if (a + b < a) para encontrar desbordamiento.

size_t es un tipo excelente para todo lo relacionado con la memoria. Lo estás haciendo bien.