我试图创建一个宏,因此我可以指定一个函数尚未实现(并且在调用时会使程序崩溃)。这就是我想出的:
#define NIMPL crash(__PRETTY_FUNCTION__ " not implemented yet")
你可以像这样使用它:
void myFunction() {
NIMPL;
}
但是,此用法会导致此错误:
../feta/include/feta.h:19:41: error: expected ‘)’ before string constant
#define NIMPL crash(__PRETTY_FUNCTION__ " not implemented yet")
^
crash()
是一个函数,它接受一个字符串作为参数,打印出消息,然后调用exit(1)
。
我可以单独确认__PRETTY_FUNCTION__
,没有连接工作正常。此外,连接两个没有__PRETTY_FUNCTION__
的字符串工作正常:"<stuff>""<other stuff>"
。但同时做两件事都行不通。
我已尝试使用stringizing operator,但它无效(如果它甚至存在于GCC中)。
答案 0 :(得分:3)
标准C和C ++提供&#34;魔术标识符&#34; __func__
,其行为就好像它是包含当前函数名称的静态char
数组的名称。 (实际上,该值是在C ++中实现定义的。)
gcc作为扩展,提供__PRETTY_FUNCTION__
,它与C的__func__
相同,并为C ++提供了一些附加信息。
这并不能解决您所问的问题,即字符串文字串联仅适用于字符串文字。
你说你的crash()
函数只需要一个字符串作为参数。
我建议修改crash()
以便它需要两个参数,或者编写一个带有两个参数的新包装函数。然后您可以使用:
#define NIMPL crash(__PRETTY_FUNCTION__, " not implemented yet")
(由于您使用的是C ++,因此可以使用相同的名称重载它。)将两个字符串连接起来作为练习。
您还可以向现有的crash()
函数添加第二个字符串参数,并为其设置默认值""
,以避免破坏现有的调用。
答案 1 :(得分:2)
在C中(因为问题最初被标记),__PRETTY_FUNCTION__
是__func__
的另一个名称,它不是字符串文字。在C ++中,它使用函数签名进行修饰,但它仍然不是字符串文字。
来自documentation(特别注意最后一句):
标识符
__func__
由翻译者隐式声明,就像紧跟在每个函数定义的左括号之后的声明一样static const char __func__[] = "function-name";
出现,其中function-name是词法封闭函数的名称。此名称是函数的简单名称。作为扩展,在文件(或在C ++,命名空间作用域)中,
__func__
计算为空字符串。
...
在C中,__PRETTY_FUNCTION__
是__func__
的另一个名称,除了在文件(或在C ++,命名空间范围)中,它的计算结果为字符串"top level"
。此外,在C ++中,__PRETTY_FUNCTION__
包含函数的签名及其名称 ...
这些标识符是变量,而不是预处理器宏,不能用于初始化char
数组或与字符串文字连接。
由于您使用的是C ++,因此可以考虑将crash
定义为可变参数模板函数而不是宏,以提供更大的灵活性。
void crash_t (std::ostringstream &oss)
{
oss << std::endl;
write(2, &oss.str()[0], oss.str().size());
exit(1);
}
template <typename A, typename... REST>
void crash_t (std::ostringstream &oss, A arg, REST... rest)
{
oss << arg;
crash_t(oss, rest...);
}
template <typename... ARGS>
void crash (ARGS... args)
{
std::ostringstream oss;
crash_t(oss, args...);
}