【问题标题】:maximum (and minimum) off_t最大(和最小)off_t
【发布时间】:2022-04-27 03:16:25
【问题描述】:

我找不到像OFF_MAX 这样可以告诉我off_t 的最大允许值的东西,所以我想知道我是否可以使用它:

#define OFF_MAX ~((off_t)1 << (sizeof(off_t) * 8 - 1))
#define OFF_MIN  ((off_t)1 << (sizeof(off_t) * 8 - 1))

我知道对有符号值的位操作通常是未定义的,但是对于 x86 和 ARM、Windows (mingw)、Linux 和 Mac OS X 是否可以?

【问题讨论】:

  • 没有接受的答案。
  • a char 不一定是 8 位。
  • 我在标准中找不到off_t。你的意思是ptrdiff_t
  • 我的意思是off_tfseekostruct stat 使用。确实是 POSIX。 off_t 在 32 位平台上可以是 64 位,这就是为什么当我将使用输入解析为 off_t 时我需要一个 OFF_MAX

标签: c limits


【解决方案1】:

在 C++(不是 C)中,你可以说

static constexpr off_t OFF_MIN = std::numeric_limits<off_t>::min();
static constexpr off_t OFF_MAX = std::numeric_limits<off_t>::max();

在 C 语言中,您没有通用 API,因此您的宏非常接近您可以做到的最佳水平。需要注意的一件事是涉及符号位的位旋转:(1 &lt;&lt; 31) - 1 会触发未定义的行为,因此即使在实际系统上,结果也不一定是0x7fffffff。 (Godbolt.) 所以你至少应该把你的 bit-twiddling 改成这样:

#define OFF_MAX ((((off_t)1 << (sizeof(off_t)*8 - 2)) - 1) * 2 + 1)
#define OFF_MIN (-OFF_MAX - 1)

接下来,为了移植到具有 24 位或 32 位 char 的 DSP,或者只是为了摆脱那个神奇的数字 8,我们可以这样做:

#define OFF_MAX ((((off_t)1 << (sizeof(off_t)*CHAR_BIT - 2)) - 1) * 2 + 1)
#define OFF_MIN (-OFF_MAX - 1)

符号幅值或反码平台(在实践中基本上不存在)的可移植性留给读者作为练习。 :) 此外,这些宏不能移植到恶意的 DeathStation 9000 实现中——例如,如果 sizeof(off_t) == 128 但其中 124 个字节只是填充。

但不要做所有这些琐碎的事情,实际上你应该这样做:

#define OFF_MAX (sizeof(off_t) == sizeof(long long) ? LLONG_MAX : sizeof(off_t) == sizeof(int) ? INT_MAX : -999999)
#define OFF_MIN (sizeof(off_t) == sizeof(long long) ? LLONG_MIN : sizeof(off_t) == sizeof(int) ? INT_MIN : -999999)

off_t 既不是 32 位也不是 64 位的系统,恕我直言,既不常见也不有价值。


最后...我在这里基本上没有经验,但是在我看来通常当您想知道off_t的有效“最大值”时,这是因为您即将做类似ftruncate(fd, x) 的事情,你想知道x 是否会抛出EFBIG 错误而不是成功。在这种情况下,你真的需要一些操作特定的东西,就像RSIZE_MAXSIZE_MAX 一样(参见Why is rsize_t defined?),或者类似于MAX_PATH 或@ 987654344@ 来自&lt;linux/limits.h&gt;RAND_MAX 来自&lt;stdlib.h&gt;

在某些系统上,可以通过以下方式访问 point-at-which-EFBIG-starts-happening(在运行时):

// #include <sys/resource.h>
rlimit lim;
getrlimit(RLIMIT_FSIZE, &lim);
printf("%zu %zu\n", (size_t)lim.rlim_cur), (size_t)lim.rlim_max));

在我的 MacBook 上,它只打印 SIZE_MAX,所以它不是很有用。

【讨论】:

    猜你喜欢
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2012-07-16
    • 1970-01-01
    • 2013-10-22
    相关资源
    最近更新 更多