混淆使用sizeof(...)运算符结果

时间:2017-02-04 05:17:07

标签: c++ c struct syntax sizeof

我最近在浏览some C++ code并遇到了the following line

static char zsocket_name[sizeof((struct sockaddr_un*)0)->sun_path] = {};

...这很令人困惑,因为它看起来好像sizeof运算符的结果被指针取消引用来访问名为sun_path的结构字段,并且该值将用于在静态存储中调整数组大小。

但是,当我尝试a simple snippet program来评估表达式sizeof((struct sockaddr_un*)0)->sun_path时,它会产生sun_path结构的sockaddr_un成员的大小。

显然,这就是原作者的意图;但我发现它在语法上令人困惑,因为它看起来像是sizeof(…)操作结果的指针取消引用。

我对sizeof(…)的使用缺少什么?为什么这个表达式会这样评估?

2 个答案:

答案 0 :(得分:4)

在C ++中,除了更常见的sizeof expression外,sizeof operator的格式为sizeof(type),因此:

sizeof ((struct sockaddr_un*)0)->sun_path

相当于:

sizeof(decltype(((struct sockaddr_un*)0)->sun_path))

前者虽然没有空格,但却是您发布的代码中的内容。

请注意,带括号的表达式也是一个表达式,因此sizeof ((struct sockaddr_un*)0)->sun_path也可以使用额外的括号编写:sizeof(((struct sockaddr_un*)0)->sun_path) - 即使这看起来像sizeof(type)形式,它也可以使用sizeof expression形式。实际上是sizeof type形式应用于带括号的表达式。

sizeof decltype(((struct sockaddr_un*)0)->sun_path)

使用declval来使用{{3}}时,更加现代的方法是在C ++中使用结构字段,而不是将0强制转换为指针。

sizeof std::declval<sockaddr_un>().sun_path

答案 1 :(得分:4)

你的错误是认为sizeof就像一个函数调用,而它实际上是一个运算符。 根本不需要使用()

sizeof实际上是sizeof expression表单的运算符,()周围expression不是必需的。 {{1}的优先级表达式实际上等于sizeof++(前缀形式),一元--+-!的表达式(逻辑和按位不是),~类型转换,(type)(地址),一元&(指针间接)和(2011年的C)*。所有这些都具有从右到左的相关性。

优先级高于_Alignof的唯一运算符为sizeof++(后缀形式),函数调用(--),()数组下标, [].访问struct成员,(仅限1999年的C)复合文字->

没有(type){list}表格。 sizeof(expression)评估表达式sizeof x的结果大小(不评估x)。 x再次评估表达式sizeof (x)的结果大小,而不进行评估。您碰巧有一个(x)形式的表达式(由于优先级规则)等同于sizeof a->b而不是sizeof (a->b)(这将触发编译错误)。