sizeof(…)运算符结果的使用令人困惑
Confusing use of sizeof(…) operator results
我最近浏览了一些C++代码,遇到了以下行:
static char zsocket_name[sizeof((struct sockaddr_un*)0)->sun_path] = {};
…这很令人困惑,因为在我看来,sizeof
运算符的结果似乎正在被指针取消引用,以访问名为sun_path
的结构字段,而该值将用于调整静态存储中的数组大小。
然而,当我尝试一个简单的代码片段程序来提取表达式sizeof((struct sockaddr_un*)0)->sun_path
时,它会产生sockaddr_un
结构的sun_path
成员的大小。
显然,这正是原作者的意图;但我发现它在语法上令人困惑,因为它看起来像是对sizeof(…)
运算结果的指针取消引用。
关于sizeof(…)
的使用,我缺少什么?为什么这个表达式是这样评价的?
在C++中,除了更常见的sizeof(type)
之外,sizeof
运算符还有一个形式sizeofexpression
,因此:
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)
形式,但它实际上是应用于带括号表达式的sizeofexpression
形式。
唯一不能做的就是sizeoftype
,所以这是无效:
sizeof decltype(((struct sockaddr_un*)0)->sun_path)
在C++中获取结构字段的一种更现代的方法是使用declval
:,而无需将0
强制转换为指针
sizeof std::declval<sockaddr_un>().sun_path
您的错误是认为sizeof
的工作原理类似于函数调用,而实际上它是一个运算符根本不需要使用()
sizeof
实际上是形式为sizeof expression
的运算符,并且不需要expression
周围的()
表达式中sizeof
的优先级实际上等于++
和--
(前缀形式)、一元+
和-
、!
和~
(逻辑和非位)、(type)
类型转换、&
(的地址)、一元*
(指针间接)和(2011年的C)_Alignof
的优先级。所有这些都具有从右到左的关联性。
唯一优先级高于sizeof
的运算符是++
和--
(后缀形式)、函数调用(()
)、[]
数组下标、访问结构成员的.
和->
,以及(仅适用于1999年的C)复合文字(type){list}
。
不存在sizeof(expression)
形式。sizeof x
计算表达式x
的结果大小(不计算x
)。sizeof (x)
计算表达式(x)
的结果大小,同样不计算。您碰巧有一个形式为sizeof a->b
的表达式,它(由于优先级规则)等效于sizeof (a->b)
,而不是sizeof(a)->b
(这会引发编译错误)。
- 使用++运算符会导致意外的结果
- 三元运算符在返回语句中给出意外的结果
- oStream 不打印添加两个 valarray 的结果(使用运算符重载)
- 当关系运算符的含义相同时,为什么结果不同?
- 有没有办法将 for 循环结果返回到像三元运算符这样的函数中?
- C++:比较运算符>和字符串文本的意外结果
- 为什么 == 运算符没有产生与 strcmp 相同的结果?
- 具有预分配结果C++的重载加运算符
- 使用 C++ 中的运算符重载显示不正确的结果
- 为什么当我使用额外的括号而不使用运算符重载时,插入运算符在 std::cout 中给出不同的结果?
- 为什么这个条件运算符的计算结果为 int?
- 为什么>>运算符在不同的编译器上显示不同的结果?
- 运算符的两个不同结果 - 在 c++11 中
- C++ 中的增量运算符未获得正确的结果
- 为什么在std :: string上尺寸运算符会产生意外结果
- 重载前增量运算符使用重载后增量运算符内的变量结果
- C++运算符和带枚举的计算结果为 false
- sizeof(…)运算符结果的使用令人困惑
- 根据运算符推断模板返回类型:结果
- 插入运算符结果后,垃圾出现在向量中