2009-07-06 18 views
53

Como título: is size_t siempre sin firmar, es decir, para size_t x, ¿es x siempre >= 0?es size_t siempre sin firmar?

+4

Alguna cita de un documento de estándares para todas las afirmaciones a continuación sería agradable. –

+4

No se trata del tamaño, es cómo lo usa :) – ralphtheninja

+8

Hay "ssize_t" para "un tamaño firmado_ :) :) –

Respuesta

44

. Es generalmente define como algo así como los (sistemas en 32-bit) siguiente:

typedef unsigned int size_t; 

Referencia:

C++ Sección Standard 18,1 define size_t es en <cstddef> que se describe en C estándar como <stddef.h>.
C Sección Standard 4.1.5 define size_t como un tipo entero sin signo del resultado de la sizeof operador

+0

@Neil: Lo sé. Fue lo primero que encontré. No tengo a mano el estándar C++, así que lo estoy descargando (mi conexión es muy lenta). Mientras tanto, pongo algo más que yo. –

+0

Bueno, tengo el estándar de C++ a mano, pero no puedo encontrarlo, posiblemente porque en realidad está definido en el estándar C (no C99). Espero que alguien lo rastree, ¡porque creo que es una pregunta interesante! –

+0

Tenga en cuenta que cplusplus.com tiene algunos sitios raros. Mira esto, por ejemplo: http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/ ahora que son firmas divertidas del operador << :) –

14

Sí, size_t se garantiza que es un tipo sin firmar.

46

Según la norma ISO 1999 C (C99), size_t es un tipo entero sin signo de al menos 16 bits (ver secciones 7.17 y 7.18.3).

La norma también recomienda que size_t no debería tener un rango de conversión de número entero mayor que long si es posible, es decir, echando size_t a unsigned long no es problemático si se sigue la recomendación.

El estándar ANSI C de 1989 (ANSI C) no menciona un tamaño mínimo o rango de conversión recomendado.

El estándar ISO 1998 C++ (C++ 98) (así como el borrador actual para C++ 0x) se refiere al estándar C. Sección 18.1 lee:

Los contenidos son los mismos que la cabecera biblioteca Standard C <stddef.h> [...]

Según la sección 1.2, esto significa que la biblioteca como se define por la norma ISO 1990 C (C90), incluyendo su primera modificación con respecto a 1995 (C95):

La biblioteca se describe en la cláusula 7 de ISO/IEC 9899: 1990 y la cláusula 7 de ISO/IEC 9899/enm.1: 1995 es de aquí en adelante llamada ed el Standard C Library.

Las partes con respecto a size_t deben ser heredados de ANSI C: frontmatter y la sección de numeración a un lado, las normas para C90 y ANSI C son idénticos. Necesitaría una copia de la enmienda normativa para asegurarme de que no hubo cambios relevantes en stddef.h, pero lo dudo. El tamaño mínimo parece ser introducido con stdint.h, es decir, C99.

Tenga en cuenta también la siguiente cita de la sección 1.2 de C++ 98:

Todas las normas están sujetas a revisión, y las partes en acuerdos basados ​​en esta norma internacional están investiguen la posibilidad de aplicar la mayor cantidad ediciones recientes de las normas indicada a continuación.

+0

Desafortunadamente, la pregunta no es sobre C99 sino C++. –

+8

@Neil, bien tiene que tomar el estándar C, porque el estándar C++ lo delega :) No define sí mismo size_t :) –

+2

Sí, pero el estándar C++ no hace referencia al estándar C99. –

5

Según el estándar, no está firmado, sin embargo, recuerdo que algunas implementaciones más antiguas usaban un tipo firmado para typedef.

Desde un documento más antiguo CCG:

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

No estoy seguro de lo importante que sería para protegerse contra eso. Mi código asume que no está firmado.

+0

Creo que todos saben que probablemente no tenga firma, pero a menos que alguien pueda citar un documento de estándares relevante, nunca lo sabremos con certeza. –

+0

No tengo el documento estándar a mano en este momento (aunque estoy seguro de que todos los estándares relevantes, C90, C99 y C++ 98 y más allá requieren que no esté firmado). Sin embargo, solo quería señalar que independientemente del estándar, existen excepciones potencialmente importantes donde size_t es un tipo firmado. –

2

El size_t debe seguir la misma definición que el estándar C, y en varios lugares en el estándar C++ implica que es unsigned natura (particularmente en las definiciones del argumento de la plantilla del asignador).

En el estándar de C++, la sección 18.1 (ISO/IEC 14882 - Primera edición 1998-01-01):

Tabla 15 enumera como tipos definidos: ptrdiff_t y size_t

3 Los contenidos son los mismos como el encabezado de la biblioteca Estándar C, con los siguientes cambios: 4 La macro NULL es una constante de puntero nulo C++ definida por la implementación en esta Norma Internacional (4.10).

El desplazamiento macro acepta un conjunto restringido de argumentos de tipo en este Estándar Internacional. tipo debe ser una estructura POD o una unión POD (cláusula 9). El resultado de aplicar el macro offset a un campo que es un miembro de datos estáticos o un miembro de función no está definido. VEA TAMBIÉN: subcláusula 5.3.3, Tamañode, subcláusula 5.7, Operadores de aditivos, subcláusula 12.5, Tienda libre, e ISO C subcláusula 7.1.6.

1

Oh, esto es simplemente terrible:

vector<MyObject> arr; 
Fill(arr); 
size_t size = arr.size(); 
for(size_t i = 1; i < size - 1; ++i) 
{ 
    auto obj = arr[i]; 
    auto next = arr[i+1]; 
} 

Ahora contemplan el caso de uso donde arr está vacía.