C++ 为什么函数地址不是常量表达式

C++ 为什么函数地址不是常量表达式,c++,compile-time,constant-expression,C++,Compile Time,Constant Expression,有没有办法在常量表达式中使用函数地址 void foo() {} int main() { static_assert(&foo, "test error"); } 这不会编译 错误C2057:应为常量表达式 这背后的意图是我想在编译时比较两个函数地址。这肯定是一个编译器错误 函数可以用作模板的模板参数,这意味着它们是常量表达式。(见附件) 此外,上面的代码可以通过gcc 4.6.1编译,虽然ideone没有编译,但ideone使用的gcc-4.5.1与您的代码相关,它有缺陷。这

有没有办法在常量表达式中使用函数地址

void foo()
{}

int main()
{
  static_assert(&foo, "test error");
}
这不会编译

错误C2057:应为常量表达式


这背后的意图是我想在编译时比较两个函数地址。

这肯定是一个编译器错误

函数可以用作模板的模板参数,这意味着它们是常量表达式。(见附件)


此外,上面的代码可以通过
gcc 4.6.1
编译,虽然ideone没有编译,但ideone使用的
gcc-4.5.1
与您的代码相关,它有缺陷。

这是我的理解,FWIW:

函数类型在编译时已知,但函数地址仅在链接时已知。因此,您可以使用函数类型作为模板参数,但在编译时地址不是常量/已知的


在示例代码中,编译器可以在编译时推断地址为非零,但无法知道具体的地址。不过,这不是编译器错误。

我认为这可能有点棘手。函数地址的问题之一是编译器不一定知道它的值(它可能在不同的翻译单元中定义,或者根本没有定义)。对于这些情况,
&foo
的预期结果是什么?(我并不是说它不能实现,这个表达式被认为是odr使用,所以编译器可以假设它必须被定义,并让链接器解析地址。如果没有定义,地址是失败的,但我会去标准中寻求对这个问题的权威答案。函数在编译时是已知的,但它们的地址不是。符号名在编译时,链接器被用于连接到内存映射。为了进一步复杂化,在C++中引入模板之后,链接器几乎都开始折叠具有相同编译代码的函数。因此,两个不同的函数在运行时可以具有相同的地址。n在加载时重新定位(想想Windows DLL),那么在程序运行之前,通常我看不到如何知道
&foo
。在链接时甚至不知道地址。代码通常在加载时重新定位。是的,但在链接时知道同一可加载模块内的相对地址,因此可以“连接”函数跳转我的观点是,函数的地址可以在运行时逻辑上获取(即:语言保证这是合法的),但不能在编译时获取。