Valores máximos para time_t (struct timespec)

Estoy usando la struct timespec y aquí está:

 struct timespec { time_t tv_sec; /* Seconds */ long tv_nsec; /* Nanoseconds */ }; 

Lo que pasa es que el usuario ingresará los valores para cada uno de estos miembros individuales, y quiero poner un cheque a un máximo. Valor que el usuario puede introducir.

¿Puedo tomar el máximo. valor de time_t como int max valor? es decir, INT_MAX para tv_sec y LONG_MAX (definido en limits.h) para tv_nsec ? ¿Cuáles serán los valores mínimos aceptables para ambos? Es cero? Supongo que los valores negativos no pueden ser aceptados? Sólo para agregar, estos valores se utilizarán en un temporizador.

PS: ¿Dónde está el typedef para time_t ? No pude encontrarlo a tiempo.

A time_t es simplemente un largo int.
Se define en (en mi sistema Linux de Linux) /usr/include/time.h, sin embargo, la definición se remonta a /usr/include/bits/types.h, donde __SLONGWORD_TYPE (que es lo que se define a __TIME_T_TYPE ) se define.

El problema con simplemente verificar si un valor es mayor que, por ejemplo, LONG_MAX , es que una vez que un valor excede este valor, se ajustará automáticamente y se convertirá en negativo. Por lo tanto, no puede verificar si algo es mayor que este valor: la macro se define como el valor más grande que puede tomar este tipo.

Realmente no desea que un usuario ingrese estos valores, a menos que “usuario” se refiera a “desarrollador”. La única forma real “segura” de probar esto sería permitir al usuario ingresar una cadena (estilo c, por supuesto) y luego ejecutar dos verificaciones:
1) Verifique si el usuario ingresó más dígitos de los permitidos (un truco barato es int(log10(number)) + 1 para contar la cantidad de dígitos en un número).
2) Si esto es igual a la cantidad de dígitos, comience a comparar dígito a dígito. Puede comparar dígito a dígito usando un poco de aritmética de módulo.

Esta es realmente la forma más segura de verificar si el usuario ingresa un número que es demasiado grande. No se encontrará con ningún problema de desbordamiento de esta manera, aunque es terriblemente tedioso. Espero que esto ayude.

Ya que las personas aquí están respondiendo cómo establecer el valor máximo de time_t , y hacer más conjeturas sobre su tipo, pensé que agregaría la forma c++ de hacerlo:

 #include  ... time_t maxTime = std::numeric_limits::max(); 

No me importaría tanto lo que pasa en un tiempo, sino lo que es razonable. En cualquier sistema que haya visto, un time_t puede codificar intervalos de tiempo desde 63 años hasta 10 11 años (casi todos los sistemas que conozco usan números de 64 bits desde que estos genios surgieron con el Y2K world-will-end end en 1999, queda por ver quién notará el “evento” mucho más grande cuando pase el año 2038).

Si razonablemente espera que su progtwig se ejecute por no más de 50 años, rechace cualquier valor mayor que 50 * 365 * 86400, o simplemente sature el valor. No espero que ninguno de los progtwigs que escribo ahora esté en uso en 50 años (aunque no viviré para verificarlo).
Por otro lado, si su sistema usa un tiempo de 32 time_t , entonces no importa de todos modos, ya que la hora del sistema se habrá desbordado en 50 años de cualquier manera, por lo que no se puede construir un tiempo significativo de todos modos sin cambiar de época.

Si preguntas “¿cuánto tiempo quieres hacer una pausa?” y el usuario dice “250 años”, consideraría que el comportamiento del progtwig no es realmente incorrecto si dijera “sí, 50 también lo haré”. Porque, hey, la diferencia realmente no es observable.

Tomado de ISO / IEC 9899: TC3 §7.23

  1. Los tipos declarados son size_t (descrito en 7.17); clock_t y time_t que son tipos aritméticos capaces de representar tiempos; y struct tm que contiene los componentes de un tiempo de calendario, llamado tiempo desglosado.

  2. El rango y la precisión de los tiempos que se pueden representar en clock_t y time_t están definidos por la implementación

Por lo tanto, no puede hacer ninguna suposición sobre su valor máximo basado en el estándar C.

Si necesita escribir un código portátil, probablemente use los autotols. Autoconf ofrece la macro AC_CHECK_SIZEOF que puede ayudarlo a lidiar con los límites de datos específicos de la architecture.

Desafortunadamente, el estándar ISO C (actualmente C11) no proporciona ninguna forma de obtener el valor máximo de time_t . Entonces, a menos que uno use herramientas como Autoconf que proporciona información, necesita hacer algunas suposiciones.

Suponiendo que time_t es un tipo entero sin bits de relleno (que es el caso en la mayoría de las plataformas en la actualidad, si no en todas), probablemente se puede tomar:

 (((time_t) 1 << (sizeof(time_t) * CHAR_BIT - 2)) - 1) * 2 + 1 

que es el valor máximo representable para un tipo entero con signo (pero el hecho de que un valor sea representable en time_t no significa que el sistema lo admita como un valor time_t ).

Uno también puede querer detectar si time_t es un tipo entero. La norma ISO C especifica que time_t es un tipo real (Cláusula 7.27.1). Por definición, un tipo real es un tipo entero o un tipo flotante real ( float , double o long double , y posiblemente otros agregados en versiones futuras del estándar, como se menciona en la Cláusula 6.11.1). Por lo tanto, si time_t no es un tipo entero, es necesariamente un tipo flotante real. Como consecuencia, se puede detectar si time_t es un tipo entero con la prueba (time_t) 1 / 2 == 0 .

Nota: El estándar C no requiere estrictamente que (T) 1 / 2 sea ​​diferente de 0 si T es un tipo flotante, pero si este no es el caso, sospecho que dichas plataformas tendrían problemas serios con los cálculos de punto flotante.

Según Wikipedia, time_t puede ser un número entero o de coma flotante, pero generalmente es un entero con signo de 32 bits o 64 bits. Creo que el mayor valor seguro que puedes asumir es INT_MAX . Para time_t al menos los números negativos son legales y se refieren a antes del 1 de enero de 1970.

Para LINUX, ctime puede aceptar cualquier time_t que mantenga el año resultante inferior o igual al límite INT_MAX, es decir, para el sistema de 64 bits:

 time_t maxtime = 67767976233521999; printf("%s\n", ctime(&maxtime)); 

Producirá la siguiente salida: Tue Dec 31 23:59:59 2147483647