C++带方括号的函数调用

C++ function call with square brackets

本文关键字:函数调用 方括号 C++      更新时间:2023-10-16

考虑:

int func(int n)
{
return n;
}
int main()
{ 
cout << func[4];
cout << func[4, 3, 5];
}

这些实际上意味着什么?我想这是关于访问func+4func在调用func[4]时分配了空间。

但是,func[4, 3, 5]简直是荒谬的。

此代码编译并func[4]不是语法错误的原因是:

1.函数类型可以隐式转换为相同类型的指针。 所以,如果我们有这样的代码:

int f(int);
using func_t = int(*)(int);
void g(func_t);

我们可以写

g(f)

并且不被迫写g(&f).&,将我们从int(int)型带到int(*)(int)型隐含地发生。

2.In C(并且必须C++以兼容(指针连接到数组,当p是指针时p[x]*(p + x)相同。所以func[4]*(func + 4)一样.

3.*(p+x)具有函数int(int)的类型,但在必要时也可以隐式衰减为指针类型。所以*(func + 4)可以隐含地只是(func + 4).

4.任何类型的指针都可以流式传输到std::cout


请注意,仅仅因为它不是语法错误并不意味着它是有效的。当然,这是未定义的行为,正如 gcc 和 clang 发出的编译器警告所表明的那样,使用函数指针的指针算术通常是错误的,因为您无法创建函数数组。该实现以它喜欢的方式放置函数。(你可以创建一个函数指针数组,但这完全是另一回事。


编辑:我应该纠正自己 - 这个答案并不完全正确。func[4]无效,因为指针不是指向对象类型的指针。@holyblackcat答案是正确的,请参阅标准中的他的答案以供参考。

这段代码应该是格式不正确的,gcc 只编译它而没有错误,因为它们默认使用非标准扩展。Clang 和 msvc 正确拒绝此代码。

我很惊讶没有答案提到它,但是:

问题中的代码根本无效C++。

它被Clang和MSVC拒绝,没有标志。海湾合作委员会拒绝了它,-pedantic-errors.

a[b](在没有运算符重载的情况下(定义为*(a + b),内置运算符+要求指针操作数是指向对象类型的指针(函数指针不是(。

[expr.add]/1

。两个操作数都应具有算术或无作用域枚举类型,或者一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整型或无作用域枚举类型。

(强调我的。


GCC 编译代码,因为默认情况下启用了允许对函数指针进行算术的扩展。

由于函数到指针衰减,func[4]被视为&(&func)[4],这实际上意味着&func + 4,它(如链接所解释的(只是将4添加到指针的数值中。调用生成的指针很可能会导致崩溃或不可预处理的结果。

std::cout没有适合打印函数指针的重载<<,编译器能够找到的最合适的重载是用于打印bool的重载。指针被转换为bool,并且由于它是非 null,它变为true,然后打印为1

最后,func[4,3,5]func[5]具有相同的效果,因为在这种情况下,,被视为运算符,并且x , y等于y

由于尚未提及:func[3, 4, 5]func[5]相同 - 其中的逗号是内置的逗号运算符,它计算左侧表达式,丢弃它,然后计算右侧表达式。此处没有发生函数调用,代码中的逗号也不分隔函数参数。

是的,这是关于访问尚未定义的func+4,从而导致垃圾值。因此,编译器将用以下警告消息指示您。

hereProgram: In function 'int main()':
Program:7: warning: pointer to a function used in arithmetic