简体   繁体   English

我可以将 size_t 类型的 sizeof 的屈服值存储在 unsigned int 对象中吗?

[英]Can I store the yield value of sizeof of type size_t in an unsigned int object?

sizeof is a standard C operator. sizeof是标准的 C 运算符。

sizeof yields the size (in bytes) of its operand in type size_t , Quote from ISO/IEC 9899:2018 (C18), 6.5.3.4/5. sizeofsize_t类型产生其操作数的大小(以字节为单位),引自 ISO/IEC 9899:2018 (C18), 6.5.3.4/5。 Phrases surrounded by -- are my addition for clarification of context:--包围的短语是我为澄清上下文而添加的:

The value of the result of both operators -- (sizeof and _Alignof) -- is implementation-defined, and its type (an unsigned integer type) is size_t , defined in <stddef.h> (and other headers).两个运算符的结果值——(sizeof 和 _Alignof)——是实现定义的,其类型(无符号整数类型)是size_t ,在<stddef.h> (和其他头文件)中定义。

Implicitly, if I want my program to be standard conform and want to use sizeof , I need to include one of the header files in which size_t is defined, because the value it yields is of type size_t and I want to store the value in an appropriate object.隐含地,如果我希望我的程序符合标准并想使用sizeof ,我需要包含其中定义size_t的头文件之一,因为它产生的值是size_t类型,我想将该值存储在一个合适的对象。

Of course, in any program which would not be a toy program I would need at least one of these headers all the way up regardless but in a simple program I need to explictly include those headers, although I do not need them otherwise.当然,在任何不是玩具程序的程序中,无论如何我都至少需要这些头文件中的一个,但在一个简单的程序中,我需要明确包含这些头文件,尽管我不需要它们。

Can I use an unsigned int object to store the size_t value sizeof yields without an explicit cast?我可以使用无符号 int 对象来存储size_tsizeof产量而无需显式转换吗?

Like for example:例如:

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

I compiled that with gcc and -Wall and -Werror option flag but it did not had anything to complain.我用gcc-Wall-Werror选项标志编译了它,但它没有什么可抱怨的。

But is that standard-conform?但这符合标准吗?

It is totally conformant, though if you have a very large object (typically 4GB or larger) its size may not fit into an unsigned int .它完全符合要求,但如果您有一个非常大的对象(通常为 4GB 或更大),其大小可能不适合unsigned int Otherwise there is nothing to worry about.否则没有什么可担心的。

Having said that, your question and this answer probably have more characters than you would save by not including an appropriate header in a lifetime worth of toy programs.话虽如此,您的问题和此答案可能包含的字符多于您在一生价值的玩具程序中不包含适当标题所节省的字符数。

It is permissible but it is your responsibility to provide that there will not be an overflow storing a value of the type size_t in an object of the type unsigned int .这是允许的,但您有责任确保将size_t类型的值存储在unsigned int类型的对象中不会发生溢出。 For unsigned integer types overflow is well-defined behavior.对于无符号整数类型,溢出是明确定义的行为。

However it is a bad programming style to use types that were not designed to store values of a wider integer type.然而,使用不是为存储更广泛的整数类型的值而设计的类型是一种糟糕的编程风格。 This can be a reason of hidden bugs.这可能是隐藏错误的原因。

Usually the type size_t is an alias for the type unsigned long .通常size_t类型是unsigned long类型的别名。 On some 64-bit systems, the type unsigned long has the same size as the type unsigned long long , which is 8 bytes instead of the 4 bytes that unsigned int can be stored in.在某些 64 位系统上, unsigned long类型与unsigned long long类型具有相同的大小,即 8 个字节,而不是unsigned int可以存储的 4 个字节。

This is allowed.这是允许的。 It is an implicit conversion ("as if by assignment").这是一个隐式转换(“好像通过赋值”)。 See the section labelled "Integer conversions":请参阅标有“整数转换”的部分:

A value of any integer type can be implicitly converted to any other integer type.任何整数类型的值都可以隐式转换为任何其他整数类型。 Except where covered by promotions and boolean conversions above, the rules are:除了上面的促销和布尔转换所涵盖的地方,规则是:

  • if the target type can represent the value, the value is unchanged如果目标类型可以表示值,则值不变
  • otherwise, if the target type is unsigned, the value 2^(b-1), where b is the number of bits in the target type, is repeatedly subtracted or added to the source value until the result fits in the target type.否则,如果目标类型是无符号的,则值 2^(b-1)(其中 b 是目标类型的位数)会被重复减去或添加到源值,直到结果适合目标类型。 In other words, unsigned integers implement modulo arithmetic.换句话说,无符号整数实现模运算。

In other words, this is always defined behaviour, but if the size is too big to fit in an unsigned int , it will be truncated.换句话说,这始终是定义的行为,但如果大小太大而无法放入unsigned int ,它将被截断。

In principle it is ok.原则上没问题。 The unsigned int can handle almost any sizeof except artificially constructed exotic things. unsigned int几乎可以处理任何sizeof除了人工构造的奇特事物。

PS I have seen code similar to yours even in Linux kernel modules. PS,即使在 Linux 内核模块中,我也看到过与您类似的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM