arr)[0]编译和等于sizeof(我的

为什么这个代码编译?

_Static uint32_t my_arr[2];
_Static_assert(sizeof(my_arr) == 8, "");
_Static_assert(sizeof(my_arr[0]) == 4, "");
_Static_assert(sizeof(my_arr)[0] == 4, "");

前两个断言显然是正确的,但我会期望最后一行失败,因为我的理解是sizeof()应该计算为一个整数字面值,它不能被视为一个数组。 换句话说,它会以与下面一行失败相同的方式失败:

_Static_assert(4[0] == 4, "");

有趣的是,以下内容确实无法编译(应该做同样的事情,不是吗?):

_Static_assert(*sizeof(my_arr) == 4, "");

错误:一元'*'的无效类型参数(具有'long unsigned int')_Static_assert(* sizeof(my_arr)== 4,“”);

如果重要,我使用gcc 5.3.0


sizeof不是一个函数。 这是一个一元运算符!~

sizeof(my_arr)[0]解析为sizeof (my_arr)[0] ,这只是sizeof my_arr[0]和冗余括号。

这就像!(my_arr)[0]解析为!(my_arr[0])

通常,后缀运算符的优先级高于前缀运算符的sizeof *a[i]++解析为sizeof (*((a[i])++)) (后缀运算符[]++适用于a第一,那么前缀运算符*sizeof )。

(这是sizeof的表达式版本,还有一个类型版本,它带有一个带括号的类型名称: sizeof (TYPE) 。在这种情况下,parens将是必需的,并且是sizeof语法的一部分。)


sizeof有两个“版本”: sizeof(type name)sizeof expression 。 前者需要一对()围绕其参数。 但后者-一个与作为参数的表达-不具有()围绕它的参数。 无论()您在参数中使用被看作是参数表达式,而不是一部分一部分sizeof语法本身。

由于my_arr已知编译器为对象的名称,而不是一个类型名称,您sizeof(my_arr)[0]实际上是由编译器视为sizeof应用于表达式: sizeof (my_arr)[0]其中(my_arr)[0]是参数表达式。 ()围绕数组名称是纯粹多余的。 整个表达式被解释为sizeof my_arr[0] 。 这相当于您之前的sizeof(my_arr[0])

(这意味着,顺便说一句,你以前的sizeof(my_arr[0])也包含一对多余的() 。)

这是一个相当普遍的误解, sizeof的语法在某种程度上需要一对()围绕它的论点。 这种误解是在解释sizeof(my_arr)[0]等表达式时误导人们的直觉。


[]sizeof有更高的优先权。 所以sizeof(my_arr)[0]sizeof((my_arr)[0])

这是一个优先表的链接。

链接地址: http://www.djcxy.com/p/3583.html

上一篇: arr)[0] compile and equal sizeof(my

下一篇: catch speeding up my code?