请查看this example。尝试使用constexpr
来获得编译时评估将是非常困难的,如果不是不可能的话。
但是,在调用函数的地方,所有参数在编译时都是已知的。理论上,(存在一些优化属性?),编译器可以暂停解析,用函数创建一个小程序,编译它,运行它,并获得结果来创建一个char常量,用于主程序编译。
我理解其中一个问题就是例如交叉编译:如果编译器可以构建一个可以在正在构建的机器上运行的程序,那么你只能从编译器运行一个程序。但这似乎无法克服。
毫无疑问:我不是第一个考虑它的人。但我试图搜索,我只能找到constexpr
和template
的东西。是否有计划在未来的任何编译器中实现此类功能?该功能也可以改为:允许在C ++源代码中编写C ++程序,编译器可以根据请求编译和运行,以创建常量。
答案 0 :(得分:3)
constexpr
和template
是C ++中强制编译器在编译时执行某些操作的唯一方法。
在许多情况下,优化器也能够找出更复杂的功能。
但是,您可能会无意中离开编译器的“舒适区”,例如,通过一些分配和/或指针算法。
正如Marc Glisse在评论中指出的那样,在您的具体示例中,您使用的是std::string
而不是本地char*
,并且由于在该类的实现中完成了魔法,优化器可能会丢失
话虽这么说,你可能会欢迎C ++ 14,它放宽了对constexpr功能的要求。 您现在可以声明局部变量,具有变异对象并具有基本控制流结构。 您也可以操作原始字符串。
https://isocpp.org/wiki/faq/cpp14-language#extended-constexpr
从更广泛的角度来看,正在进行一项研究,以便为编程语言提供升级服务。 暂存是通过显式代码构造部分评估程序的想法,甚至允许在编译时执行最复杂的函数。 从不同角度来看问题的一些示例方法:
请注意,这些都没有尝试在C ++中这样做。
答案 1 :(得分:2)
你基本上想要的东西与标准C ++提供的不同。请注意,语言标准没有定义需要哪些优化,而只是大多数优化都是合法的。
CyghusX1 answer给出一些一般性提示。
如果您使用的是POSIX(例如Linux),您还可以在“运行时”生成一些专用的 C ++代码,分叉它的编译,并使用动态加载工具(即{{1} })生成的“插件”;更具体一点:
dlopen
-rdynamic -ldl
功能。extern "C" int foo(const char*)
函数;避免name mangling)int foo(const char*)
/tmp/temp1234.cc
的内容将其编译作为共享对象进行分支,例如使用system(3)或其他内容g++ -O -Wall -fPIC /tmp/temp1234.cc -shared -o /tmp/temp1234.so
在/tmp/temp1234.so
上致电dlopen(3);检查是否失败(否则,请使用RTLD_NOW|RTLD_GLOBAL
)dlerror()
外部名称在dlsym
提供的句柄上调用dlopen
。这给出了一个函数指针,稍后可以调用它。在Linux上,您可以重复多次(实际上,至少数十万次,请参阅我的manydl.c示例)。我的GCC MELT工具正在做这些事情。
实际上,GCC MELT用于自定义和扩展GCC编译器,您甚至可以用于实现目标,因为它可以自定义GCC;所以你可以添加一些标记你想要专门化的函数的新属性或编译指示,并对进行专业化的MELT扩展进行编码(你需要理解GCC internals,特别是Gimple,这样就可以了超过一周,您的foo
可以使用您的MELT扩展程序提供的部分附加 GCC内置版本。)
所以有像
这样的东西__COMPACT_PRETTY_FUNCTION__
并编写实现新#define __COMPACT_PRETTY_FUNCTION__ _builtin_compact_pretty_function()
内置编译器的MELT扩展。