Kon*_*app 87 c++ pointers function-pointers
我无法弄清楚这一点:
int main() {
int (*) (int *) = 5;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的赋值用g ++ c ++ 11编译.我知道这int (*) (int *)是一个指向函数的指针,它接受一个(int *)as参数并返回一个int,但是我不明白你怎么能把它等同于5.起初我认为它是一个不断返回5的函数(来自我最近的学习) F#,可能,哈哈),然后我简单地想,函数指针指向内存位置5,但这显然不起作用,并且十六进制值也不行.
认为这可能是因为函数返回一个int,并且分配一个int是好的(不知何故),我也试过这个:
int * (*) (int *) = my_ptr
Run Code Online (Sandbox Code Playgroud)
where my_ptr是类型int *,与第二个函数指针的类型相同,如第一种类型为int的情况.这不编译.分配5或任何int值,而不是my_ptr,也不编译此函数指针.
那么作业是什么意思呢?
更新1
我们已经确认这是一个错误,如最佳答案所示.但是,仍然不知道您分配给函数指针的值实际发生了什么,或者赋值的情况.任何(好的)解释都将非常感谢!有关问题的详细说明,请参阅下面的编辑.
编辑1
我使用的是gcc版本4.8.2(在Ubuntu 4.8.2中)
编辑2
实际上,将它等同于我的编译器.甚至将它等同于std :: string变量,或者返回double的函数名,也可以.
编辑2.1
有趣的是,使它成为一个函数指针,指向任何返回不是指针的数据类型的函数,将让它进行编译,例如
std::string (*) () = 5.6;
Run Code Online (Sandbox Code Playgroud)
但是只要函数指针指向返回某个指针的函数,它就不会编译,例如with
some_data_type ** (*) () = any_value;
Run Code Online (Sandbox Code Playgroud)
oua*_*uah 59
这是g ++中的一个错误.
int (*) (int *)
Run Code Online (Sandbox Code Playgroud)
是一个类型名称.
在C++中,您不能使用没有标识符的类型名称声明.
所以这用g ++编译.
int (*) (int *) = 5;
Run Code Online (Sandbox Code Playgroud)
这也编译:
int (*) (int *);
Run Code Online (Sandbox Code Playgroud)
但它们都是无效的声明.
编辑:
TC在评论bugzilla bug 60680中提到了一个类似的测试案例,但尚未获得批准.臭虫在bugzilla中得到证实.
编辑2:
当上面的两个声明位于文件范围时,g ++正确发出诊断(它无法在块范围内发出诊断).
编辑3:
我检查过,我可以在最新版本的g ++版本4(4.9.2),最新的预发布版本5(5.0.1 20150412)和最新的实验版本6(6.0.0 20150412)上重现该问题.
Edw*_*ard 27
它不是有效的C++.请记住,因为您的特定编译器恰好编译它不会使其有效.与所有复杂软件一样,编译器有时会出现错误,这似乎是一个错误.
相比之下clang++抱怨:
funnycast.cpp:3:11: error: expected expression
int (*) (int *) = 5;
^
funnycast.cpp:3:18: error: expected '(' for function-style cast or type construction
int (*) (int *) = 5;
~~~ ^
funnycast.cpp:3:19: error: expected expression
int (*) (int *) = 5;
^
3 errors generated.
Run Code Online (Sandbox Code Playgroud)
这是预期的行为,因为违规行不是有效的C++.它声称是一个赋值(因为=),但不包含任何标识符.
正如其他答案所指出的,这是一个错误
int (*) (int *) = 5;
编译.预期具有含义的这种陈述的合理近似是:
int (*proc)(int*) = (int (*)(int*))(5);
现在proc是一个指向函数的指针,它希望5地址成为一个函数的基地址,该函数接受int*并返回一个int.
在某些微控制器/微处理器上5可能是有效的代码地址,并且可能在那里找到这样的功能.
在大多数通用计算机上,存储器的第一页(0-10234K页的地址)故意无效(未映射)以捕获null指针访问.
因此,虽然行为取决于平台,但是可以合理地期望在*proc被调用时发生页面错误(例如,(*proc)(&v)).在*proc调用的时间之前,没有任何异常发生.
除非您正在编写动态链接器,否则您几乎肯定不应该在数字上计算地址并将它们分配给指针到函数变量.