Pregunta

Algunos antecedentes:Si quería utilizar para, por ejemplo, scanf() para convertir una cadena en un estándar de tipo entero, como uint16_t, Yo uso la SCNu16 de <inttypes.h>, como este:

#include <stdio.h>
#include <inttypes.h>
uint16_t x;
char *xs = "17";
sscanf(xs, "%" SCNu16, &x);

Pero más raro de tipo entero como pid_t no tiene ninguna de estas cosas;sólo el normal de los tipos enteros son apoyados por <inttypes.h>.Para convertir de otra manera, a portable printf() un pid_t, Puedo echarlo a intmax_t y el uso de PRIdMAX, como este:

#include <stdio.h>
#include <inttypes.h>
#include <sys/types.h>
pid_t x = 17;
printf("%" PRIdMAX, (intmax_t)x);

Sin embargo, no parece ser una manera de portabilidad scanf() en un pid_t.Así que esta es mi pregunta:Cómo hacerlo portable?

#include <stdio.h>
#include <sys/types.h>
pid_t x;
char *xs = 17;
sscanf(xs, "%u", &x);  /* Not portable! pid_t might not be int! /*

Pensé scanf()ing a un intmax_t y, a continuación, comprobar que el valor está dentro pid_t's límites antes de la conversión en pid_t, pero no parece ser una forma de obtener el valor máximo o mínimo para pid_t.

¿Fue útil?

Solución

Hay un robusto y portátil de solución, que es el uso de strtoimax() y de verificación de los desbordamientos.

Es decir, analizar un intmax_t, compruebe un error de strtoimax(), y , a continuación, también ver si "encaja" en un pid_t por colada y su comparación con el original intmax_t valor.

#include <inttypes.h>
#include <stdio.h>
#include <iso646.h>
#include <sys/types.h>
char *xs = "17";            /* The string to convert */
intmax_t xmax;
char *tmp;
pid_t x;                    /* Target variable */

errno = 0;
xmax = strtoimax(xs, &tmp, 10);
if(errno != 0 or tmp == xs or *tmp != '\0'
   or xmax != (pid_t)xmax){
  fprintf(stderr, "Bad PID!\n");
} else {
  x = (pid_t)xmax;
  ...
}

No es posible utilizar scanf(), porque (como dije en un comentario) scanf() no lo va a detectar desbordamientos.Pero yo estaba equivocado al decir que ninguno de los strtoll()las funciones relacionadas con toma una intmax_t; strtoimax() no!

También no uso otra cosa que strtoimax() a menos que usted sabe el tamaño de su tipo entero (pid_t, en este caso).

Otros consejos

Depende de exactamente cómo portátil que usted desea ser.POSIX dice que pid_t es un entero con signo tipo de las utilizadas para almacenar los Identificadores de proceso y proceso de Identificaciones de grupo.En la práctica, se podría asumir con seguridad que long es lo suficientemente grande.En su defecto, su intmax_t debe ser lo suficientemente grande (por lo que aceptará cualquier válido pid_t);el problema es, que tipo podría aceptar valores que no son legítimos en pid_t.Usted está atrapado entre una roca y un lugar duro.

Me gustaría utilizar long y no te preocupes mucho acerca de él, excepto por un oscuro comentario en algún lugar que un software arqueólogo de 100 años, por lo tanto, encontrar y observar da una razón por la que el 256-bits de la CPU está crujiendo a detener el momento de la entrega de 512 bits de valor como un pid_t.

POSIX 1003.1-2008 ya está disponible en la web (todos los 3872 páginas, en formato PDF y HTML).Usted tiene que registrarse (gratis).Yo llegué a él a partir de la Grupo Abierto De La Librería.

Todo lo que veo ahí es que debe ser un entero con signo tipo.Claramente, todas válidas entero con signo de los valores de ajuste en intmax_t.No puedo encontrar ninguna información en <inttypes.h> o <unistd.h> que indica PID_T_MAX o PID_T_MIN o de otros valores (pero sólo he esta noche tengo acceso a ella, por lo que podrían estar escondidos donde no he buscado).OTOH, estoy de pie por mi comentario original - yo creo que los valores de 32 bits son pragmáticamente adecuado, y me gustaría utilizar long de todos modos, lo que sería de 64 bits en 8-bits máquinas.Supongo que, aproximadamente, la peor cosa que podría suceder es que un "adecuadamente privilegiada" proceso de lectura de un valor que era demasiado grande, y se envía una señal a un proceso equivocado debido a un desajuste de los tipos.No estoy convencido de que estaría preocupado de que.

...oooh!...p400 bajo <sys/types.h>

La aplicación será compatible con uno o más entornos de programación en el que los anchos de blksize_t, pid_t, size_t, ssize_t, y suseconds_t no son mayores que el ancho de tipo long.

Si está realmente preocupado, puede _assert(sizeof(pid_t) <= long) o el tipo que elija para su material '%'.

Como se explica en esta respuesta , la especificación dice signed int. Si 'int' cambia, su '% u' por definición cambia con él.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top