(*&a)是左值还是右值?

时间:2019-08-28 11:42:40

标签: c operators rvalue lvalue unary-operator

首先,我认为这是interface Foo<T, K extends keyof T> { key: K; map: (value: T[K]) => any; } ,但以下事实改变了我的想法。

我尝试使用rvalue作为表达式,它可以正常工作,但是运算符&(*&a)只能与&一起使用,因此lvalue(*&a) ,为什么呢?

2 个答案:

答案 0 :(得分:1)

此表达式&(&a)无效,将不起作用。

根据C Stnadard

  

1一元&运算符的操作数应为一个函数   指示符,是[]或一元*运算符,或左值的结果   指定不是位字段且未声明的对象   和寄存器存储类说明符。

  

3一元&运算符产生其操作数的地址。如果   操作数的类型为“ type”,结果的类型为“ pointer to type”。如果   该操作数是一元*运算符的结果,该运算符都不是   也不对&运算符求值,结果就像两个   省略了,只不过对操作员的约束仍然适用   结果不是左值。

因此,表达式&a的结果不是左值。因此,您可能无法将运算符&应用于&&a之类的表达式。

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    int x = 10;
    &( &x );

    return 0;
}

编译器gcc 8.3发出错误

prog.c: In function ‘main’:
prog.c:7:2: error: lvalue required as unary ‘&’ operand
  &( &x );
  ^

此表达式*&a有效,结果为左值。

  

4一元*运算符表示间接。如果操作数指向a   函数,结果是一个函数指示符; 如果它指向一个   对象,结果是一个左值指定对象。如果   操作数的类型为“要输入的指针”,结果的类型为“类型”。如果   无效的值已分配给指针,   一元*运算符未定义。

请记住,括号不影响所包围的表达式是否为左值。

答案 1 :(得分:1)

根据C 2018 6.5.3.2 4(讨论unary *运算符),一元*的结果是一个左值:

  

…如果操作数指向一个函数,则结果为一个函数指示符;否则为0。如果它指向一个对象,则结果是一个指定该对象的左值。……

这告诉我们*&a是左值。但是,问题中询问的表达式是(*&a),因此我们必须考虑括号的作用。

6.3.2.1 2(讨论自动转换)似乎告诉我们(*&a)转换为*&a中的值,而不是左值:

  

除了它是sizeof运算符的操作数之外,一元&运算符,++运算符,--运算符或.的左操作数除外运算符或赋值运算符,将不具有数组类型的左值转换为存储在指定对象中的值(不再是左值);这称为左值转换

但是,6.5.1 5(讨论带括号的表达式)与此矛盾:

  

带括号的表达式是主要表达式。它的类型和值与非括号表达式相同。如果未加括号的表达式分别是一个左值,一个函数标记或一个空表达式,则它是一个左值,一个函数标记或一个空表达式。

这是C标准的缺陷; 6.5.1 5和6.3.2.1 2相互矛盾。我们需要了解的是,专门针对括号表达式的6.5.1 5优先于更通用的6.3.2.1 2,这就是所有C实现的行为方式。

因此(*&a)是一个左值。