0

我正在尝试为一个项目重新实现一些 coreutils,并且我看到 TYPE_MINIMUM(some int) 很多,但是我看不到它的定义位置或它的任何用法。我不确定它是在制作过程中产生的,还是故意的。有任何想法吗?

我已经包含了函数所需的所有头文件,并且一切正常,直到调用 TYPE_MINIMUM 进行验证。

正在使用的文件的完整来源:https ://github.com/coreutils/coreutils/blob/master/src/who.c

static const char *idle_string (time_t when, time_t boottime)
{
    static time_t now = TYPE_MINIMUM (time_t);

    if (now == TYPE_MINIMUM (time_t))
        time (&now);

    if (boottime < when && now - 24 * 60 * 60 < when && when <= now)
    {
        int seconds_idle = now - when;
        if (seconds_idle < 60)
            return "  .  ";
        else
        {
            static char idle_hhmm[IDLESTR_LEN];
            /* FIXME-in-2018: see if this assert is still required in order
               to suppress gcc's unwarranted -Wformat-length= warning.  */
            assert (seconds_idle / (60 * 60) < 24);
            sprintf (idle_hhmm, "%02d:%02d",
                     seconds_idle / (60 * 60),
                     (seconds_idle % (60 * 60)) / 60);
            return idle_hhmm;
        }
    }

    return (" old ");
}
error: ‘TYPE_MINIMUM’ was not declared in this scope
4

1 回答 1

0

这个宏的实现可以在 Coreutils “intprops.h” 文件中找到。

从那个文件:

/* The maximum and minimum values for the integer type T.  */
#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
#define TYPE_MAXIMUM(t)                                                 \
  ((t) (! TYPE_SIGNED (t)                                               \
        ? (t) -1                                                        \
        : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1)))

其中 TYPE_WIDTH 以位为单位给出类型的大小:

/* The width in bits of the integer type or expression T.
   Do not evaluate T.
   Padding bits are not supported; this is checked at compile-time below.  */
#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

它通过取该类型最大值的反码来获得该类型的最小值。它通过以下任一方式获得最大值:

  • 如果它是无符号的,则将值 -1 转换为该类型
  • 如果它是有符号的,则将通过设置第二高位获得的值减去 1 获得的值加一到两倍。

尽管您的问题并不真正需要它,但我想通过那个已签名的案例。让我们int16_t举个例子。

如果我们提前处理该三元和 TYPE_WIDTH,并忽略额外的括号以确保更安全TYPE_MAXIMUM(int16_t),则扩展为:

(int16_t) ((((int16_t) (1 << 14)) - 1) * 2 + 1)

然后:

(int16_t) ((((int16_t) 0x4000) - 1) * 2 + 1)

然后:

(int16_t) (((int16_t) 0x3FFF) * 2 + 1)

然后:

(int16_t) ((int16_t) 0x7FFE + 1)

然后:

(int16_t) ((int16_t) 0x7FFE + 1)

这是:

(int16_t) 0x7FFF

TYPE_MAXIMUM是一种在不依赖有符号溢出的情况下有效地设置除高位以外的所有位的方法,这会产生未定义的行为并且不得使用。

TYPE_MAXIMUM方法确实假定给定的任何带符号类型都不使用模型,其中最大带符号值不由设置的最高位表示。

ATYPE_MINIMUM(int16_t)将反转这些位以获得(int16_t) 0x8000.

TYPE_MINIMUM来自最大值方法假设给定的任何有符号类型不使用符号和大小算术,或任何其他模型,其中最大保持值的反码不是最小值。

由于对有符号表示的这两个限制,此表中给出的可与TYPE_MINIMUM宏一起使用的表示是一个补码和二进制补码。

实际上,这可能永远不会成为问题,几乎所有内容都使用有符号整数的二进制补码表示。

于 2019-07-25T14:21:45.000 回答