sirve que para long c++ signed size-t

que - string c++



¿Cómo detectar un número negativo asignado a size_t? (2)

El problema con emitir una advertencia para esto es que no es un comportamiento indefinido de acuerdo con el estándar. Si convierte un valor firmado en un tipo sin signo del mismo tamaño, más tarde puede convertirlo de nuevo en un valor firmado y obtener el valor original en cualquier compilador compatible con los estándares.

Además, el uso de valores negativos convertidos a size_t es una práctica bastante común para varias condiciones de error: muchas llamadas del sistema devuelven un valor sin signo ( size_t u off_t ) para el éxito o un -1 (convertido a sin signo) para un error. Entonces, agregar una advertencia de este tipo al compilador causaría advertencias falsas para gran parte del código existente. POSIX intenta codificar esto con ssize_t , pero eso interrumpe las llamadas que pueden tener éxito con un valor de retorno mayor que el valor firmado máximo para ssize_t .

Esta declaración se compila sin advertencias en g ++ -pedantic -Wall (versión 4.6.3):

std::size_t foo = -42;

Menos visiblemente falso es declarar una función con un argumento size_t y llamarla con un valor negativo. ¿Puede una función de este tipo proteger contra un argumento negativo involuntario (que aparece como mil millones de dólares, obedeciendo a §4.7 / 2)?

Respuestas incompletas:

El solo hecho de cambiar size_t a (firmado) por largo tiempo descarta la semántica y otras ventajas de size_t.

Cambiarlo a ssize_t es simplemente POSIX, no Estándar.

Cambiarlo a ptrdiff_t es frágil y a veces está roto.

La prueba de valores enormes (conjunto de bits de orden superior, etc.) es arbitraria.


El siguiente extracto es de una biblioteca privada.

#include <limits.h> #if __STDC__ == 1 && __STDC_VERSION__ >= 199901L || / defined __GNUC__ || defined _MSC_VER /* Has long long. */ #ifdef __GNUC__ #define CORE_1ULL __extension__ 1ULL #else #define CORE_1ULL 1ULL #endif #define CORE_IS_POS(x) ((x) && ((x) & CORE_1ULL << (sizeof (x)*CHAR_BIT - 1)) == 0) #define CORE_IS_NEG(x) (((x) & CORE_1ULL << (sizeof (x)*CHAR_BIT - 1)) != 0) #else #define CORE_IS_POS(x) ((x) && ((x) & 1UL << (sizeof (x)*CHAR_BIT - 1)) == 0) #define CORE_IS_NEG(x) (((x) & 1UL << (sizeof (x)*CHAR_BIT - 1)) != 0) #endif #define CORE_IS_ZPOS(x) (!(x) || CORE_IS_POS(x)) #define CORE_IS_ZNEG(x) (!(x) || CORE_IS_NEG(x))

Esto debería funcionar con todos los tipos sin firmar.