指向函数的指针转换的澄清

3

函数类型(左值)可以转换为函数指针(右值)。

int func();
int (*func_ptr)() = func;

但是从(4.1/1)可以看出:

非函数、非数组类型T的左值(3.10)可以被转换为右值。

这是否意味着函数不会进行左值到右值的转换?此外,当数组退化为指针时,它不是返回一个指针作为右值吗?

1个回答

3

函数是lvalue。指向函数的指针(一种数据类型)可以是lvalue;如果您给它一个名称,则为lvalue;否则,它不是(粗略地说)。指向函数的指针遵循所有通常的lvalue到rvalue转换规则。对于基本类型或指针等简单类型,lvalue到rvalue转换基本上意味着读取变量。

void func();            //  Declares func
(*(&func))();           //  The expression &func is an rvalue
void (*pf)() = &func;   //  pf is an lvalue
(*pf)();                //  In the expression *pf, pf undergoes an
                        //  lvalue to rvalue conversion

请注意函数自动转换为函数指针,且()运算符适用于函数和函数指针,因此最后两行可以这样写:
void (*pf)() = func;
pf();

和往常一样,转换的结果是一个右值(除非转换为引用类型)。当一个数组被隐式转换为指针时,这也是适用的;数组和函数都只能存在为左值,但它们都隐式地转换为指针,这是一个右值。但是该指针可以用来初始化相应指针类型的变量;这些变量是左值。


我明白了,所以结果只是一个地址,并不意味着你正在读取某个值。对吗? - user1086635
什么的结果?将函数转换为指针的结果是一个值,即函数的地址。它在内存中没有地址(这是lvalue的特征)。 - James Kanze
函数 func 的结果是一个 rvalue,它是一个地址,但不是从非函数或非数组类型返回的 rvalue 的意义上,这就是为什么 (4.1/1) 中的语句是正确的原因? - user1086635
1
关于§4.1,它只是说函数或数组没有左值到右值的转换。它并未提及其他转换,例如从数组到指针或从函数到指针(其结果是右值,因为转换的目标类型不是引用)。 - James Kanze
1
@user1086635 我不会完全这样描述,但很接近。显式使用 & 运算符是取函数的地址:& 运算符的操作数必须是左值,结果是右值。隐式转换是一种转换,而不是 & 运算符。但转换的结果是右值,并且转换的语义与使用 & 运算符相同。因此,在实践中,在底层发生的事情没有任何区别。 - James Kanze
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接