为什么定义sizeof实现的结果?

时间:2016-06-10 14:35:06

标签: c++ c sizeof

在C99中,§6.5.3.4:

  

2 awk运算符产生其操作数的大小(以字节为单位),   它可以是表达式或类型的带括号的名称。 ...

     

4结果的值是实现定义的,及其类型(a   无符号整数类型)是sizeof,在size_t(和其他   头)。

在C ++ 14中,§5.3.3:

  

1 <stddef.h>运算符产生对象中的字节数   表示其操作数。 ... sizeof的结果适用于任何   其他基本类型(3.9.1)是实现定义的。

唯一保证的值是sizeofsizeof(char)sizeof(unsigned char),即一个。

然而,“对象表示中的字节数”对我来说似乎很不错。例如,在C99§6.2.6.1中:

  

4存储在任何其他对象类型的非位字段对象中的值   由 n × CHAR_BIT 位组成,其中 n 是对象的大小   该类型的,以字节为单位。 ...

那么为什么它是实现定义的,如果看起来很明确?

你们当中许多人似乎误解了我的问题。我从未声称:

A)类型的大小在所有系统上定义或相同,

B)实现定义意味着它可以返回“随机值”

我在这里得到的是sizeof(signed char)是一个固定的公式。公式本身不能在实现之间改变。是的,n * CHAR_BITS可以是4个字节或8个字节。我明白了。但在所有实现之间,值必须为int

5 个答案:

答案 0 :(得分:12)

sizeof的结果是实现定义的,因为各种基本类型的大小是实现定义的。我们对C ++中类型大小的唯一保证是

sizeof(char) = 1 and sizeof(char) <= sizeof(short) <= sizeof(int) <= 
sizeof(long) <= sizeof(long long)

并且每种类型都具有最小值,它必须支持C11 [附件E(资料性附录)实施限制] / 1

  

[...]显示的最小幅度应由具有相同符号的实施定义幅度代替。[...]

#define CHAR_BIT    8
#define CHAR_MAX    UCHAR_MAX or SCHAR_MAX
#define CHAR_MIN    0 or SCHAR_MIN
#define INT_MAX     +32767
#define INT_MIN     -32767
#define LONG_MAX    +2147483647
#define LONG_MIN    -2147483647
#define LLONG_MAX   +9223372036854775807
#define LLONG_MIN   -9223372036854775807
#define MB_LEN_MAX  1
#define SCHAR_MAX   +127
#define SCHAR_MIN   -127
#define SHRT_MAX    +32767
#define SHRT_MIN    -32767
#define UCHAR_MAX   255
#define USHRT_MAX   65535
#define UINT_MAX    65535
#define ULONG_MAX   4294967295
#define ULLONG_MAX  18446744073709551615

因此,按照标准,int必须能够存储一个可以存储在16位中的数字,但它可以更大,而在今天的大多数系统中它都是32位。

  

我在这里得到的是n * CHAR_BITS是一个固定的公式。公式本身不能在实现之间改变。是的,int可以是4个字节或8个字节。我明白了。但在所有实现之间,值必须为n * CHAR_BITS

您是正确的,但根据C99§6.2.6.1定义n

  

其中n是该类型的对象的大小

强调我的

因此公式可能是固定的,但n不固定,同一系统上的不同实现可以使用不同的n值。

答案 1 :(得分:5)

sizeof 的结果不是实现定义的。标准没有说;它说:

  

结果的 是实现定义的,[...]

这在语义上是不同的。 sizeof的结果定义明确:

  

[...]其操作数的大小(以字节为单位)[...]

此上下文中的一个字节的位宽和非char类型中的字节数都是实现定义的。

答案 2 :(得分:1)

因为基本类型的大小是根据效率定义的,而不是根据确切的位数来定义的。 “int”必须是CPU可以有效操作的东西。对于大多数现代系统,此数量结果为32位(或64位)。对于较旧的系统,它通常是16位。但是,如果存在35位CPU,则此类系统上的int将为35位。换句话说,C ++没有应用惩罚来强制CPU可能根本不支持的位宽。

当然,人们可能会争辩说,基本类型的奇异位宽的概念已经被历史所取代。我想不出任何不支持8位,16位和32位标准集的现代CPU(随意不同意这个说法,但至少可以举一个例子!),64位也很漂亮常见的(如果硬件支持不可用,在软件中支持并不是很重要)。

可以说C ++语言已经远离了char的可变位数;据我所知,u8“...”转换为char *,但是unicode规范要求u8以8位编码。

如果8位的字符大小为1,则32位的int为大小4.如果16位的字符大小为1,则32位的int仅为大小2.两种情况在C ++,如果这些大小恰好是各自硬件的好选择。

答案 3 :(得分:-1)

  

填充位是“未指定”而不是“实现定义”。

错误。非常非常错误。未指定填充字节的。这里的意图是这些位的值可能代表陷阱值,但不一定。

标准告诉您sizeof返回bytes * CHAR_BITS,但不指定大小(精确宽度类型除外)。类型占用的字节数是实现定义的,因此sizeof也必须如此。

实施定义被描述为:

  

未指定的值,其中每个实现文档的选择方式如何   是

答案 4 :(得分:-1)

在示例中声明一个新变量时:

size_t a;

它将与此相同:

unsigned short int a; // unsigned short a

在32位计算机上,整数(int)的大小为4个字节。 short int的大小是2个字节。

在C编程中,lan​​guange&#39; size_t&#39;是&size;(&#39; sizeof()&#39;的返回类型。 operator.When使用&#39; sizeof()&#39;操作员他会给你对象的大小。&size;(&#39; sizeof()&#39;必须是l值类型。元素(对象)的大小不能是负数,它必须是整数。