我正在使用struct timespec
结构,这里是:
struct timespec {
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds */
};
事情是,用户将输入每个成员的值,我想要检查最多。用户可以输入的值。
我可以拿最大值吗? time_t
的值为int max value? INT_MAX
tv_sec
和LONG_MAX
tv_nsec
(在limits.h中定义)time_t
?两者的最低可接受值是多少?它是零吗?我猜不能接受负值?只需添加,这些值将在计时器中使用。
P.S:{{1}}的typedef在哪里?在time.h中找不到它。
答案 0 :(得分:26)
由于此处的人们正在回答如何设置最大time_t
值,并进一步猜测其类型,我想我会添加c++
方式来执行此操作:
#include <limits>
...
time_t maxTime = std::numeric_limits<time_t>::max();
答案 1 :(得分:3)
time_t只是一个长整数
它在(在我的Ubuntu linux系统上)/usr/include/time.h中定义,但是该定义一直延伸到/usr/include/bits/types.h,其中__SLONGWORD_TYPE
(这是{ {1}}定义为)已定义。
简单地检查一个值是否大于__TIME_T_TYPE
的问题是,一旦某个值超过此值,它将自动回绕并变为负数。因此,您无法检查是否有任何值大于此值 - 宏被定义为此类型可以采用的最大值。
您并不真的希望用户输入这些值 - 除非“用户”是指“开发人员”。测试这个的唯一真正的“安全”方法是让用户输入一个字符串(当然是c风格),然后运行两个检查:
1)检查用户是否输入了多于允许的数字(便宜的技巧LONG_MAX
来计算数字中的位数)。
2)如果这等于数字位数,则开始逐位比较。您可以使用一些模运算来逐位比较。
这是检查用户是否输入太大的数字的最安全的方法。你不会以这种方式遇到任何溢出问题,尽管 非常单调乏味。 希望这会有所帮助。
答案 2 :(得分:3)
我不太关心time_t
的内容,而是关于什么是合理的。在我见过的任何系统上,time_t
可以编码时间跨度从63年到10 11 年(几乎我所知道的每个系统都使用64位数字,因为这些天才提出来了在1999年的Y2K世界即将结束的事情中,当2038年过去时,谁会注意到更大的“事件”还有待观察。
如果您合理地期望您的程序将运行不超过50年,请拒绝任何大于50 * 365 * 86400的值,或者只是使该值饱和。我不认为我现在写的任何程序在50年内都会被使用(虽然我不会对此进行验证)。
另一方面,如果您的系统 使用32位time_t
,那么无论如何都无关紧要,因为无论如何系统时间都会在50年内溢出,所以可以'无论如何都要构建一个有意义的时间而不会改变时代。
如果你问“你想暂停多久?”并且用户说“250年”,如果你说“是的,50也会做”,我认为这不是真正错误的程序行为。因为,嘿,差异确实是不可观察的。
答案 3 :(得分:2)
取自ISO/IEC 9899:TC3§7.23
声明的类型为
size_t
(在7.17中描述);clock_t
和time_t
是能够表示时间的算术类型;和 保存日历时间组件的struct tm
,称为 破碎的时间。- 醇>
clock_t
和time_t
中可表示的时间范围和精度是实现定义的
因此,您无法根据C标准对其最大值进行任何假设。
如果您需要编写可移植代码,您可能会使用autotols。 Autoconf提供了AC_CHECK_SIZEOF宏,可以帮助您处理特定于体系结构的数据限制。
答案 4 :(得分:2)
不幸的是,ISO C标准(目前为C11)没有提供任何方法来获得time_t
的最大值。因此,除非使用Autoconf提供信息等工具,否则需要做出一些假设。
假设time_t
是没有填充位的整数类型(现在大多数平台就是这种情况,如果不是全部的话),可以采取:
(((time_t) 1 << (sizeof(time_t) * CHAR_BIT - 2)) - 1) * 2 + 1
这是有符号整数类型的最大可表示值(但是time_t
中的值可表示的事实并不意味着系统支持它作为time_t
值。< / p>
还可能想要检测time_t
是否为整数类型。 ISO C标准规定time_t
是实际类型(条款7.27.1)。根据定义,真实类型是整数类型或实际浮动类型(float
,double
或long double
,以及如第6.11.1条所述,可能在标准的未来版本中添加其他版本。因此,如果time_t
不是整数类型,则它必然是实数浮点类型。因此,可以使用测试time_t
检测(time_t) 1 / 2 == 0
是否为整数类型。
注意:如果(T) 1 / 2
是浮动类型,则C标准并不严格要求T
与0不同,但如果不是这种情况,我怀疑此类平台会出现严重问题用浮点计算。
答案 5 :(得分:1)
根据维基百科,time_t
可以是整数或浮点数,但通常是32位或64位有符号整数。我认为您可以假设的最大安全值是INT_MAX
。对于time_t
,至少负数是合法的,并在1970年1月1日之前提及。
答案 6 :(得分:0)
对于LINUX,ctime
可以接受任何time_t
,它将使结果年份低于或等于INT_MAX限制,即对于64位系统:
time_t maxtime = 67767976233521999;
printf("%s\n", ctime(&maxtime));
将产生以下输出:Tue Dec 31 23:59:59 2147483647
答案 7 :(得分:0)
这应该为您提供任何 POSIX 机器和任何架构上 time_t 的最大值,只要 time_t 是无符号整数(非浮点)类型。它被写入与机器的字长和任何填充位无关。使用 cc -DDEBUG
编译以获得一些诊断信息:
#include <time.h>
#include <stdint.h> /* uintmax_t */
#include <stdio.h> /* fprintf() */
#include <limits.h> /* CHAR_BIT, UINT_MAX */
#include <inttypes.h> /* format spec PRIX64:
* ll/l + X on 32/64-bit arch */
/* The following two routines (should) work for any integer
* representation in either 2's or 1's complement and for any
* #bits per byte (CHAR_BIT could be <> 8).
*/
/* Count the bits set in any unsigned integer type (plus any signed
* iff using 2's complement integer representation).
* Returns the precision (width - padding bits - sign bit) iff given
* the xxx_MAX value of any integer type, signed or unsigned.
* From SEI CERT C Coding Standard:
* Rules for Developing Safe, Reliable, and Secure Systems (2016)
*/
size_t popcount (uintmax_t num)
{
size_t cnt = 0;
while (num != 0) {
if (num % 2 == 1)
cnt++;
num >>= 1;
}
return cnt;
}
#define PRECISION(max_value) popcount(max_value)
#define SIGN_BIT (1)
#ifndef MIN
#define MIN(a, b) ((a) < (b)? (a): (b))
#endif
/* Get the maximum value of a time_t from it's storage width.
* On error: returns (time_t)(-1) iff time_t is longer than an
* intmax_t (which would mean it's a floating point type and
* longer than an intmax_t).
* ASSERTION: time_t is a signed integer type,
* i.e. not (unsigned, but the bit pattern of (-1) treated special).
*/
time_t get_time_t_max (void)
{
time_t t0, t1 = (time_t)(-1);
size_t size = sizeof(time_t);
size_t prec;
uintmax_t max;
if (sizeof(time_t) > sizeof(uintmax_t))
return t1;
/* Get an uintmax_t with all bits set that could be in a time_t.
* We can not do this calculation with a time_t as long we do
* not know its precision (overflow could occur).
*/
prec = MIN (PRECISION (UINTMAX_MAX), CHAR_BIT * sizeof(time_t));
max = (uintmax_t) 1 << (prec - 1);
max = max|(max - 1);
t0 = max; /* maybe truncation happens here */
/* Now account for any padding bits */
prec = PRECISION(t0) - SIGN_BIT;
t0 = (time_t) 1 << (prec - 1);
t1 = t0|(t0 - 1);
#ifdef DEBUG
fprintf (stderr, "time_t_max\t= 0x%"PRIX64"\n", (uint64_t) t1);
fprintf (stderr, "sizeof(time_t)\t= %3zd byte\n", size);
fprintf (stderr, "precision\t= %3zd bit\n", prec);
fprintf (stderr, "padding\t\t= %3zd bit\n",
CHAR_BIT*size - prec - SIGN_BIT);
fprintf (stderr, "bits per byte\t= %3d bit\n", CHAR_BIT);
#endif /* DEBUG */
return t1;
}
#undef SIGN_BIT
/*! vi: set ai tabs=8 shiftwidth=4: */
答案 8 :(得分:-1)
# include <sys/time.h>
# include <time.h>
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h> /* printf() */
# include <inttypes.h> /* format spec PRIX64: ll/l + X on 32/64-bit arch */
# include <limits.h> /* INT_MAX */
/* This is portable, more or less */
time_t
approx_time_t_max()
{
struct tm tm;
time_t t0, t1;
tm.tm_isdst = -1;
tm.tm_min = tm.tm_sec = 59;
tm.tm_mday = tm.tm_hour = 23;
fprintf (stderr, "Please be patient, this takes loooong...(hours --
occasionally showing the year)...");
for (tm.tm_year = 99999 - 1900; tm.tm_year <= INT_MAX; tm.tm_year++) {
if (tm.tm_year % 49999 == 0)
fprintf (stderr, "%d", tm.tm_year - 1900);
else if (tm.tm_year % 2503 == 0)
fprintf (stderr, ".");
for (tm.tm_mon = 0; tm.tm_mon <= 11; tm.tm_mon++)
#if 0
for (tm.tm_mday = 21; tm.tm_mday <= 31; tm.tm_mday++)
if (tm.tm_mon == 1 && tm.tm_mday > 28)
continue;
else
//for (tm.tm_hour = 20; tm.tm_hour <= 23; tm.tm_hour++)
//for (tm.tm_min = 0; tm.tm_min <= 59; tm.tm_min++)
//for (tm.tm_sec = 0; tm.tm_sec <= 59; tm.tm_sec++)
#endif /* commented out */
if ((t0 = mktime (&tm)) == (time_t)(-1))
goto out;
else t1 = t0;
}
out: /* NOP */ ;
/* FIXME not portable: time_t can be a floating point type,
* or any integer type other than long or long long.
*/
fprintf (stderr, "time_t_max = 0x%"PRIX64"\n", t1);
return t1;
}