int(*)(int *)= 5(或任何整数值)的含义

我无法弄清楚这一点:

int main() { int (*) (int *) = 5; return 0; } 

上面的任务用g ++ c ++ 11编译。 我知道int (*) (int *)是一个函数的指针,它接受一个(int *)作为参数,并返回一个int,但我不明白你怎么可以将它等于5.起初我以为它是一个不断返回5的函数(从我最近学习的F#中,可能是哈哈),然后我简单地想,函数指针指向内存位置5,但是这不起作用,很明显,也不是hex值。

认为这可能是因为该函数返回一个int,并分配一个int是好的(不知何故),我也试过这个:

 int * (*) (int *) = my_ptr 

其中my_ptr的types为int * ,与第二个函数指针的types相同,如第一种情况下的types为int。 这不会编译。 赋值5或者任何int值,而不是my_ptr ,也不会为这个函数指针编译。

那么这个任务是什么意思?

更新1

我们已经确认这是一个错误,如最佳答案所示。 但是,我们仍然不知道实际发生的情况是您分配给函数指针的值是什么,或者赋值时发生了什么。 任何(好)的解释,将非常感激! 请参阅下面的编辑,以更清楚地了解这个问题。

编辑1

我使用的是gcc版本4.8.2(在Ubuntu 4.8.2中)

编辑2

其实,把它等同于我的编译器。 即使将它等同于一个std :: stringvariables,或者返回一个double的函数名也是可行的。

编辑2.1

有趣的是,把它作为函数指针指向任何返回不是指针的数据types的函数,都会让它编译,比如

 std::string (*) () = 5.6; 

但是,只要函数指针指向一个返回某个指针的函数,它就不会编译,如

 some_data_type ** (*) () = any_value; 

这是g ++中的一个bug。

  int (*) (int *) 

是一个types名称。

在C ++中,不能使用没有标识符的types名称进行声明。

所以这个编译与g ++。

  int (*) (int *) = 5; 

这也编译:

  int (*) (int *); 

但他们都是无效的声明。

编辑

TC在评论bugzilla错误60680中提到了类似的testing用例, 但尚未获得批准 。 这个bug在bugzilla中得到确认。

编辑2

当上述两个声明在文件范围内时,g ++正确地发出一个诊断(它不能在块范围发出诊断)。

编辑3

我检查了一下,我可以在最新版本的g ++版本4(4.9.2),最新的预发布版本5(5.0.1 20150412)和最新的实验版本6(6.0.0 20150412)上重现这个问题。

这是无效的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. 

这是预期的行为,因为违规行是无效的C ++。 它声称是一个任务(因为= ),但不包含标识符。

正如其他答案已经指出,这是一个错误

int (*) (int *) = 5;

编译。 这个陈述的合理近似值可能会有一个含义:

int (*proc)(int*) = (int (*)(int*))(5);

现在, proc是一个指向函数的指针,它要求地址5是一个函数的基地址,它接受一个int*并返回一个int

在一些微控制器/微处理器5可能是有效的代码地址,并且可能在那里定位这样的function。

在大多数通用计算机上,为了捕获null指针访问,内存的第一页(4K页面的地址0-1023 )被故意无效(未映射)。

因此,当行为取决于平台时,可以合理地期望在调用*proc时发生页面错误(例如(*proc)(&v) )。 在*proc被调用之前,没有什么不寻常的事情发生。

除非你正在编写一个dynamic连接器,否则你几乎肯定不应该用数值计算地址,并把它们分配给指向函数的variables。

 /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/cc1plus.exe -da so.cpp 

这个命令行生成了很多中间文件。 第一个, so.cpp.170r.expand说:

 ... int main() () { int D.2229; int _1; ;; basic block 2, loop depth 0 ;; pred: ENTRY _1 = 0; ;; succ: 3 ;; basic block 3, loop depth 0 ;; pred: 2 <L0>: return _1; ;; succ: EXIT } ... 

这仍然不能回答究竟发生了什么,但它应该是朝着正确的方向迈出的一步。