¿Debo usar size_t o ssize_t? [duplicate]

5 minutos de lectura

avatar de usuario de hgyxbll
hgyxbll

En mi código, no uso int o int sin firmar. Solo uso size_t o ssize_t para portátiles. Por ejemplo:

typedef size_t intc;    // (instead of unsigned int)
typedef ssize_t uintc;  // (instead of int)

Porque strlen, string, vector… todo uso size_tpor lo que suelo usar size_t. y solo uso ssize_t cuando puede ser negativo.

Pero encuentro que:

Los tipos de enteros sin signo son ideales para usos que tratan el almacenamiento como una matriz de bits. Usar un sin signo en lugar de un int para ganar un bit más para representar enteros positivos casi nunca es una buena idea. Los intentos de garantizar que algunos valores sean positivos mediante la declaración de variables sin signo normalmente se verán frustrados por las reglas de conversión implícitas.

en el libro El lenguaje de programación C++.

Así que estoy desconcertado. ¿Me equivoco? ¿Por qué STL no cumple con la sugerencia del libro?

  • size_t utilizado en la biblioteca estándar para representar tamaños. Sería extraño si el tamaño del contenedor pudiera ser negativo. La interfaz indica su comportamiento. Creo que el libro asume el uso diario, no la interfaz

    – kasak

    1 de abril de 2013 a las 7:49

  • @kassak: no, en este caso, un tipo sin firmar en realidad es solía obtener un bit extra por el valor. Algunos miembros del comité vieron importante poder tener una std::vector<char> mayor que la mitad de la memoria disponible. Y la cita dice “casi nunca”…

    – Bo Person

    1 de abril de 2013 a las 8:03


  • Nomine para reabrir ya que el duplicado citado no aborda esta publicación lo suficientemente cerca.

    – chux – Reincorporar a Monica

    24 de noviembre de 2015 a las 18:48


  • Usando intc para no firmado size_t (como usted dice, ‘[signed] int‘ en comentario, aunque probablemente sea más largo), y uintc para firmado ssize_t (‘unsigned int‘ en el comentario), es confuso para mí, porque normalmente el ‘tú’ representa no firmadop.ej uint32_t es el no firmado versión de int32_tun entero de 4 bytes.

    – RastaJedi

    20 de agosto de 2016 a las 20:39

  • A los que marcaron como duplicado. Esto definitivamente no es un duplicado. La pregunta no es sobre firmado vs no firmado, pero size_t vs ssize_t, es decir, “¿cuándo debo usar cualquiera de los dos”?

    – EnzoR

    12 de octubre de 2017 a las 13:06

avatar de usuario de maditya
maditya

ssize_t se utiliza para funciones cuyo valor de retorno podría ser un tamaño válido o un valor negativo para indicar un error. Se garantiza poder almacenar valores al menos en el rango [-1, SSIZE_MAX] (SSIZE_MAX depende del sistema).

Así que deberías usar size_t siempre que quiera devolver un tamaño en bytes, y ssize_t siempre que devuelva un tamaño en bytes o un valor de error (negativo).

Ver:
http://pubs.opengroup.org/onlinepubs/007908775/xsh/systypes.h.html

  • Bueno, esta respuesta no explica completamente las consecuencias de basar tales decisiones en consideraciones puras de interfaz. Es poco probable que alguna implementación use un tipo más amplio para ssize_t de lo que usa para size_t. Esto significa inmediatamente que el precio que pagará por la capacidad de devolver valores negativos es reducir a la mitad del rango positivo del tipo. Es decir SSIZE_MAX es usualmente SIZE_MAX / 2. Esto debe tenerse en cuenta. En muchos casos no vale la pena pagar este precio solo por la posibilidad de regresar -1 como un valor negativo.

    – AnT apoya a Rusia

    25 de diciembre de 2014 a las 19:56


  • @AnT tener valores sin firmar es uno de los mayores fracasos en C++. No hay caso en el que no valga la pena pagar el precio. Si necesita números tan grandes, use int64_t en su lugar…

    – el Santo

    2 mayo 2015 a las 11:01

  • @thesaint ¿De qué diablos estás hablando? No se trata de capacidad. ¿Cómo agregaría cuatro al puntero de la pila si su valor actual puede o no ser negativo?

    – josafatv

    17/09/2015 a las 23:33

  • ¿No surgieron enteros sin signo? primero (antes de los firmados) debido al hardware; obviamente, esto está más cerca de C sin sistema operativo que la mayoría del uso de C ++, pero el uso de MSB para permitir la aritmética firmada no se hizo solo para reducir a la mitad la magnitud absoluta que podría representar un “entero”. sino porque había una necesidad de matemáticas sustractivas. las entradas firmadas y las entradas sin firmar son peras y manzanas: ¡diferentes pero capaces de cruzarse en ciertas circunstancias limitadas…! (Se comparte la mitad del rango de cada uno.)

    – Sly Sven

    14/01/2016 a las 17:57


  • Donde parece surgir la confusión, para mí, es cuando una función que parece que debería producir solo un valor sin signo, es decir, la cantidad de bytes que read(2) ha sido capaz de leer realmente. Sin embargo, en el caso de un error, se devuelve el valor de -1 (probablemente codificado como TODOS los bits configurados), no para dificultar las cosas, sino porque es un centinela valor que no puede surgir normalmente.

    – Sly Sven

    14/01/2016 a las 17:59

avatar de usuario de user657267
usuario657267

ssize_t no está incluido en el estándar y no es portátil. size_t debe usarse cuando se manipula el tamaño de los objetos (hay ptrdiff_t también, por diferencias de puntero).

  • ssize_t es de POSIX: pubs.opengroup.org/onlinepubs/009696799/basedefs/sys/…

    – Kafumanto

    9 de enero de 2017 a las 13:34

  • C++ 11 y posterior implementa la plantilla std::make_signedpero es un área algo gris si se usa size_t ya que su parámetro está bien definido. En c ++ 20, el uso de esta plantilla con tipos no permitidos por el estándar da como resultado un código mal formado, pero las implementaciones existentes permiten el uso de size_t

    – Swift – Pastel de viernes

    1 de julio de 2020 a las 15:34

¿Ha sido útil esta solución?