简体   繁体   English

如果函数具有外部链接,则在编译时检查

[英]Check at compile-time if function has external linkage

Is it possible to check at compile time if a function pointer points to a function with external linkage? 如果函数指针指向具有外部链接的函数,是否可以在编译时检查?

What I'm imagining is a type traits-style template that returns whether or not a function pointer has external linkage. 我想象的是一个类型特征风格的模板,它返回一个函数指针是否有外部链接。

void linked() {}

void test() {
  // Returns true, since `linked` will have external linkage.
  bool fn = has_external_linkage<linked>::value;

  auto unlinked = []() {};
  constexpr auto *unlinked_ptr = +unlinked;

  // Returns false, since function pointers to lambdas
  // have no external linkage.
  bool lambda = has_external_linkage<unlinked_ptr>::value;
}

Reasoning 推理

What I really care about is whether it's valid to pass a function pointer as a template parameter. 我真正关心的是将函数指针作为模板参数传递是否有效。 The following code fails in GCC, stating that fn does not have external linkage. 以下代码在GCC中失败,说明fn没有外部链接。

template <typename FnType, FnType fn>
void call() {
  fn();
}

int main(int argc, char** argv) {
  auto lambda = []() {};
  constexpr *lambda_ptr = +lambda;
  call<decltype(lambda_ptr), lambda_ptr>();
  return 0;
}

If I swap out lambda_ptr for a constexpr pointer to a regular function, the code compiles fine, since the function will have external linkage. 如果我将lambda_ptr指向常规函数的constexpr指针,则代码编译正常,因为该函数将具有外部链接。

Essentially, I'd like to be able to avoid the runtime overhead of sending a function pointer whenever it's possible to encode it as a template parameter. 本质上,我希望能够避免在可以将其编码为模板参数时发送函数指针的运行时开销。 However, I'd still like to be able to send the function pointer when it can't be a template parameter. 但是,当它不能作为模板参数时,我仍然希望能够发送函数指针。 Hence, I'd like to construct something like a has_external_linkage template so I can choose the appropriate path. 因此,我想构建类似于has_external_linkage模板的东西,以便我可以选择适当的路径。

IMHO, using function address as template parameter is UB and you should never use that. 恕我直言,使用函数地址作为模板参数是UB,你永远不应该使用它。 Reason is, that for different compilers on different platforms function address may be unknown right to execution time. 原因是,对于不同平台上的不同编译器,函数地址可能是未知的执行时间。

That it work on architectures which have VM and assign static virtual addresses to local functions didn't mean anything, since UB allowed to work in any way, even one what you expect it to work ;) 它适用于具有VM并为本地功能分配静态虚拟地址的体系结构并不意味着任何事情,因为UB允许以任何方式工作,甚至是您希望它工作的一种方式;)

Instead, as was proposed in some other question, you can pass function object by value. 相反,正如在其他一些问题中提出的那样,您可以按值传递函数对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM