为什么size of(My_Arr)[0]编译而等号(my_arr[0])?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

为什么这段代码要编译?

_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, "");

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

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

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

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

错误:一元‘的无效类型参数*‘’(有‘长时间没有签名的int’)_静态_断言(*相当大的(我的)_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])

一般来说,在C中后缀操作符比前缀操作符具有更高的优先级。sizeof *a[i]++解析为sizeof (*((a[i])++))(后缀运算符)[]++适用于a首先,前缀操作符*sizeof)。

(这是sizeof,还有一个类型版本,它使用括号大小的类型名称:sizeof (TYPE),在这种情况下,父母是必需的,并且是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])

(这意味着,BTW,你以前的sizeof(my_arr[0])还包含一对多余的())

这是一种相当普遍的误解sizeof的语法需要一对()围绕着它的论点。这种误解就是在解释诸如sizeof(my_arr)[0]

扫码关注云+社区