函数未实现宏

Function not implemented macro?

本文关键字:实现 函数      更新时间:2023-10-16

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

#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>"。但是同时做这两件事是行不通的。

我已经尝试使用字符串化操作符,但它没有工作(如果它甚至存在于GCC中)。

标准C和c++提供了"魔术标识符" __func__,它的作用就好像是包含当前函数名称的静态char数组的名称。(实际上这个值是c++中实现定义的)

gcc作为扩展,提供了__PRETTY_FUNCTION__,与C的__func__相同,并为c++提供了一些额外的信息。

这并不能解决你所问的问题,即字符串字面值连接只适用于字符串字面值。

你说你的crash()函数接受一个字符串作为参数。

我建议修改crash(),使其接受两个参数,或编写一个新的包装器函数,接受两个参数。然后可以使用:

#define NIMPL crash(__PRETTY_FUNCTION__, " not implemented yet")

(因为你使用c++,你可以用相同的名字重载它。)将两个字符串连接起来作为练习。

您还可以为现有的crash()函数添加第二个字符串参数,并给它一个默认值"",以避免破坏现有的调用

在C中(正如问题最初标记的那样),__PRETTY_FUNCTION____func__的另一个名称,它不是字符串文字。在c++中,它是用函数签名修饰的,但它仍然不是字符串字面值。

来自文档(特别注意最后一句话):

标识符__func__由翻译器隐式声明,就好像紧跟在每个函数定义的开始大括号之后,声明

static const char __func__[] = "function-name";
出现了

,其中function-name是词法封闭函数的名称。此名称是函数的原始名称。作为扩展名,在file(或者,在c++中,命名空间作用域),__func__计算结果为空字符串。

…在C语言中,__PRETTY_FUNCTION____func__的另一个名字,除了在file(或者,在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...);
}