为什么要编译这段代码?
_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
发布于 2017-10-10 03:12:44
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
语法的一部分。)
发布于 2017-10-10 03:14:21
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]
时误导直觉的原因。
发布于 2017-10-10 03:12:31
[]
比sizeof
具有更高的优先级。所以sizeof(my_arr)[0]
和sizeof((my_arr)[0])
是一样的。
Here是指向优先表的链接。
https://stackoverflow.com/questions/46653406
复制相似问题