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

我不明白:

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

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

我想这可能是因为函数返回了一个整型数,赋值一个整型数是可以的(不知何故) ,我还试了下面这个方法:

int * (*) (int *) = my_ptr

其中,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;

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

some_data_type ** (*) () = any_value;
11669 次浏览

It's a bug in g++.

 int (*) (int *)

is a type name.

In C++ you cannot have a declaration with a type name without an identifier.

So this compiles with g++.

 int (*) (int *) = 5;

and this compiles as well:

 int (*) (int *);

but they are both invalid declarations.

EDIT:

T.C. mentions in the comments bugzilla bug 60680 with a similar test case but it has not yet been approved. The bug is confirmed in bugzilla.

EDIT2:

When the two declarations above are at file scope g++ correctly issues a diagnostic (it fails to issue the diagnostic at block scope).

EDIT3:

I checked and I can reproduce the issue on the latest release of g++ version 4 (4.9.2), latest pre-release version 5 (5.0.1 20150412) and latest experimental version 6 (6.0.0 20150412).

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

This command line generates a lot of intermediate files. The first of them, so.cpp.170r.expand, says:

...
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


}
...

This still doesn’t answer what happens exactly, but it should be a step in the right direction.

It is not valid C++. Remember that because your particular compiler happens to compile it doesn't make it valid. Compilers, like all complex software, sometimes have bugs and this appears to be one.

By contrast clang++ complains:

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.

This is the expected behavior because the offending line is not valid C++. It purports to be an assignment (because of the =) but contains no identifier.

As other answers have pointed out, it is a bug that

int (*) (int *) = 5;

compiles. A reasonable approximation of this statement that would be expected to have a meaning is:

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

Now proc is a pointer-to-function that expects the address 5 to be the base address of a function that takes an int* and returns an int.

On some microcontrollers/microprocessors 5 might be a valid code address, and it might be possible to locate such a function there.

On most general-purpose computers, the first page of memory (addresses 0-1023 for 4K pages) are purposely invalid (unmapped) in order to catch null pointer accesses.

Thus, while behavior depends on the platform, one can reasonably expect a page fault to occur when *proc is invoked (e.g., (*proc)(&v)). Before the time at which *proc is invoked, nothing unusual happens.

Unless you are writing a dynamic linker, you almost certainly shouldn't be numerically calculating addresses and assigning them to pointer-to-function variables.