使用Define抛出异常

Using Define for throwing exceptions

本文关键字:抛出异常 Define 使用      更新时间:2023-10-16

目前,我正在重构一些旧项目,这些项目是由我们的一些前员工编写的。我遇到过用define包装抛出异常的情况。

像这样:

#define THROWIT(msg) throw common::error(msg)

代码中的例子:

#define THROW_FD_ERROR( fd, op )
throw common::error_fd( errno,
    __ERR_FD_API_3
    .arg( fd )
    .arg( op )
    .arg( strerror(errno) ),
    __FILE__,
    __LINE__ )

我可以看到它的一些好处,但他们不是那么大,我这样做。不管怎样,这是一种常见的技术吗?在你看来,可以从中获得什么好处?是否使用定义来抛出异常?如果有,目的是什么?

UPD: add define from code

UPD2:谢谢大家的回答。我决定去掉所有的宏。为了调试,我将用回溯信息扩展基本错误类,在我看来,这比仅仅使用文件和行的标准定义要好。

通常,只有当您需要特定于预处理器的特性时才使用预处理器,如__FILE____LINE__。这个宏没有做任何函数不能做的事情,因此它非常非典型和糟糕。

给出的宏并没有很多好处。

但是,如果您想在异常消息中包含文件名、函数名和行号,宏可以有一个好处:
#define POSSIBLY_USEFUL_THROWIT(msg) throw common::error(__FILE__, __FUNCTION__, __LINE__, msg)

哦,THROWIT是一个可怕的名字。


Alf强调了一个很好的观点:

您可以使用宏来收集信息,这是唯一的方法去做。然而,将其与异常的抛出联系起来是一种错误责任合并。这意味着你需要独立例如用于日志记录、UI消息等的宏。一个宏

我想他的意思是拥有这样的东西:

// Construct new temporary object source_line_info
#define CURRENT_SRC_LINE_INFO() common::source_line_info(__FILE__, __FUNCTION__, __LINE__)

,然后像这样使用:

throw common::error(CURRENT_SRC_LINE_INFO(), msg);

只对真正需要它的部分进行宏化。

就我个人而言,我更喜欢有一个额外的宏,如
#define THROW_COMMON_ERROR(...)  throw common::error(CURRENT_SRC_LINE_INFO(), ...

因为如果我要在多行上有一个"宏调用",我不妨让它尽可能简短和集中,即使这意味着引入另一个宏。

No。不喜欢。坏的。它使代码更难以理解,而且输入也不那么短。

如果必须的话,使用函数。但是我不认为你真的需要,在这种情况下。

的优点是要键入的字符较少,并且可以在单个点(宏)更改抛出声明(例如抛出另一种类型)。但是,您也可以使用通常的函数来代替宏。在一个函数可以做完全相同的事情的地方使用宏被认为不是一个好的做法,因为宏有一些问题(比如没有作用域和可能污染包含宏定义头文件的其他文件)。当没有其他语言特性可以做同样的事情,而你又迫切需要它的时候,宏至多只是一个工具。

不,最好在c++中使用内联函数。宏的替换不需要编译器的检查。预处理器宏应该在没有其他方法执行任务时使用。