从该函数中获取函数的地址

时间:2017-12-07 14:49:38

标签: c language-lawyer

首先,问题是:你有什么理由不能从该函数中获取函数的地址吗?

#include <stdio.h>

struct foo {
  void(*xf)(void);
  int r;
} sFoo;

void func(void) {
  sFoo.xf = func; /* <-- like this */
}

int main()
{
  func();
  printf("FuncPtr  is: %p\n", sFoo.xf);
  printf("FuncAddr is: %p\n", &func);
  getchar();
  return 0;
}

我无法想到为什么这不应该移植,但这并不意味着没有。我在Windows上使用MinGW和MSVC进行了测试,在Ubuntu上使用gcc进行了测试,它运行正常。 C标准几乎是无声的,除了说(C99 5.1.1.2)函数引用在最终转换阶段得到解决。

我的主要恶化是我无法找到确认这是标准行为的任何内容。我在过去的评论中表示,你无法从该函数中获取函数的地址,我认为当时这是伪造的,但没有&# 39;到现在为止,我真的有时间或倾向于实际检查它。

2 个答案:

答案 0 :(得分:8)

  

是否有任何理由不能从该函数中获取函数的地址?

不。

  

C标准非常安静,只是说(C99 5.1.1.2)函数引用在最终转换阶段得到解决。

标准不沉默;它只是没有解决那个特定情况显式。这不是特例。

  

我的主要恶化是我找不到任何证实这是标准行为的东西。

该标准规定您可以获取函数的地址,并描述如何。函数定义中的代码也不例外,因此一般规则适用于此。如果你无法在该函数的实现中获得指向函数的指针,那实际上会非常不一致,因为你当然可以从那里调用递归)。 / p>

  

我过去曾经说过你说你不能从那个函数中取一个函数的地址,我认为当时这个函数是伪造的,但是没有真正的时间或倾向于实际上检查一下,直到现在。

我倾向于同意这些评论在任何程度上都被误导为标准C。但是,他们可能针对某些不合规的实施。或者也许你错了。显然,我不能特别针对任何此类评论,除非您提供参考,并且最好在您的问题中提供上下文引用。

答案 1 :(得分:2)

一元&运算符的唯一约束如下:

  

一元&amp;的操作数运算符应该是函数指示符,[]或一元*运算符的结果,或者是左值   指定一个不是位字段且未声明的对象   寄存器存储类说明符。

函数标识符满足此要求(可能与直觉相反,函数标识符是按6.3.2.1p1的左值),因此获取其地址始终是合法的。

事实上,如果它是非法的,递归函数是不可能的,因为要调用一个函数,你需要使用它的指示符,并且6.3.2.1p4在转换为函数指针方面定义了这样的用法: / p>

  

函数指示符是具有函数类型的表达式。除了   当它是sizeof运算符的操作数时,_Alignof   操作员,65)或一元&amp;运算符,类型的函数指示符   ''函数返回类型''被转换为具有的表达式   输入“指向函数返回类型的指针”。