功能未实现宏?

时间:2016-10-31 21:24:29

标签: c++ gcc

我试图创建一个宏,因此我可以指定一个函数尚未实现(并且在调用时会使程序崩溃)。这就是我想出的:

#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中)。

2 个答案:

答案 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...);
}