【问题标题】:Can I store the yield value of sizeof of type size_t in an unsigned int object?我可以将 size_t 类型的 sizeof 的屈服值存储在 unsigned int 对象中吗?
【发布时间】:2020-06-19 02:43:06
【问题描述】:

sizeof 是标准 C 运算符。

sizeof 产生size_t 类型的操作数的大小(以字节为单位),引用自 ISO/IEC 9899:2018 (C18), 6.5.3.4/5。 -- 包围的短语是我为了澄清上下文而添加的:

两个运算符的结果值——(sizeof 和 _Alignof)——是实现定义的,其类型(无符号整数类型)是size_t,在<stddef.h>(和其他头文件)中定义。

隐含地,如果我希望我的程序符合标准并希望使用sizeof,我需要包含一个定义了size_t 的头文件,因为它产生的值是size_t 类型我想将值存储在适当的对象中。

当然,在任何不是玩具程序的程序中,我都需要至少一个这些头文件,但在一个简单的程序中,我需要明确包含这些头文件,尽管我不需要它们.

我可以使用无符号 int 对象来存储 size_tsizeof 产生而不需要显式转换吗?

例如:

char a[19];
unsigned int b = sizeof(a);

我用 gcc-Wall-Werror 选项标志编译了它,但它没有什么可抱怨的。

但这符合标准吗?

【问题讨论】:

  • 只要数字足够小以适合无符号整数。
  • @user253751 只要它在unsigned int 的范围内,顺便说一句,这真的不是那么小,这样就可以了?
  • IMO unsigned int b = sizeof(a); 形式上是错误的,因为如果 sizeof 是 64 位,unsigned int 是 32 位,如果 a 的大小大于 0xffffffff(即不过不太可能)。
  • @Jabberwocky 什么是 f.e. unsigned long 还是 unsigned long long int?那会更合适吗?
  • @RobertSsupportsMonicaCellio 标准中说long int 大于或等于int 类型的大小,所以没有没有保证。最好使用size_t。但正如我之前提到的,如果你的对象大小是“合理的”,你可以务实地使用任何无符号的 32 位类型。

标签: c type-conversion sizeof unsigned-integer size-t


【解决方案1】:

原则上是可以的。 unsigned int 几乎可以处理任何sizeof,除了人工构建的奇异事物。

附:即使在 Linux 内核模块中,我也见过与您类似的代码。

【讨论】:

    【解决方案2】:

    这是允许的,但您有责任确保在unsigned int 类型的对象中存储size_t 类型的值不会发生溢出。对于无符号整数类型,溢出是明确定义的行为。

    但是,使用并非旨在存储更宽整数类型值的类型是一种糟糕的编程风格。这可能是隐藏错误的原因。

    通常size_t 类型是unsigned long 类型的别名。在某些 64 位系统上,unsigned long 类型的大小与 unsigned long long 类型的大小相同,都是 8 个字节,而不是 unsigned int 可以存储的 4 个字节。

    【讨论】:

    • 好的,存储空间问题已记录。非常感谢。但是,如果我使用例如unsigned long long 而不是使用size_t,那将是完全正确的?有什么好抱怨的?
    • @RobertSsupportsMonicaCellio 但是使用size_t 有什么问题?
    • @RobertSsupportsMonicaCellio 不会有问题的。但是它会使代码的读者感到困惑。
    • @Jabberwocky 只是为了避免包含标题。不多不少。这个问题主要是为了好奇。但我想知道是否有任何函数需要显式的size_t 参数而不是例如unsigned long long,如果我以后需要使用b
    • @RobertSsupportsMonicaCellio 事实上,所有标准的 C 字符串函数都需要一个 size_t 类型的参数 abd 具有返回类型 size_t 例如 strlen、strspn、strcspn 等。
    【解决方案3】:

    它完全符合要求,但如果您有一个非常大的对象(通常为 4GB 或更大),它的大小可能不适合 unsigned int。否则没什么好担心的。

    话虽如此,您的问题和此答案的字符数可能比您在终生值得的玩具程序中不包含适当的标题所节省的字符多。

    【讨论】:

    • 如果我会使用unsigned long int unsigned long long int
    • @RobertSsupportsMonicaCellio 如果你能解释使用它们的原因,为什么不呢。故意将对象大小保存为较小的类型,我认为这主要是因为必须在 32 位上下文中使用大小,并且使用 64 位类型最终将需要截断。尽管其他人的答案告诉你什么,但更早地使用常量进行截断会更安全,并且可以拯救你。
    【解决方案4】:

    这是允许的。它是一个implicit conversion(“好像通过分配”)。请参阅标有“整数转换”的部分:

    任何整数类型的值都可以隐式转换为任何其他整数类型。除上述促销和布尔转换涵盖的情况外,规则如下:

    • 如果目标类型可以表示值,则值不变
    • 否则,如果目标类型是无符号的,则将值 2^(b-1)(其中 b 是目标类型中的位数)重复地减去或添加到源值,直到结果适合目标类型。换句话说,无符号整数实现了模运算。

    换句话说,这始终是已定义的行为,但如果大小太大而无法放入unsigned int,它将被截断。

    【讨论】:

      猜你喜欢
      • 2013-10-20
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 2010-09-13
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多