10

我有自己的返回类型和函数定义如下:

typedef enum xx_return_t {
   success = 0,
   general_error = -1,
   specific_error = -2,
   [...]
} xx_return_type;

xx_return_type generalFunction(void) {
   if(there_was_an_error)
      return general_error;
}

但是我对这里的错误类型值有点不确定; C/C++ 中错误返回值的标准/最佳实践是什么 -负数还是正数

更新: 感谢您的回答!我一直在寻找有关 C 和 C++ 的信息,但我也意识到这对每种语言特定的一般结构和方法(异常、错误代码、对象返回等)提出了很好的问题。

4

5 回答 5

17

这实际上是伪装成一个的两个完全不同的问题(C 和 C++ 版本)。

在 C++ 中,答案很简单:对...返回的数据值使用返回值,并对错误/异常情况使用异常。不要在纯 C++ 中使用返回值进行错误检查(C 库 API 到 C++ 是另一回事)。

在 C 中你没有那个选项,所以我建议使用 0 表示成功,使用负数表示错误代码。如果需要,这可以灵活地使用正数来获取其他成功信息(例如read呼叫)

于 2012-10-04T13:40:12.717 回答
4

C++:

  1. 这是一个选择问题,我都见过。
  2. 使用例外!
于 2012-10-04T13:17:02.887 回答
3

有多种约定可供选择:

  • microsoft 对其大多数高级 api 使用 0=FALSE=error。并让用户使用全局函数查找特定错误GetLastError()
  • microsoft 将 0=ok 用于较低级别的 API,例如注册表、音频或电话。这些都返回一个类似于 的类型HRESULT,包含特定的错误代码。
  • 返回状态的posix函数通常返回-1表示错误,并让用户通过全局变量查找错误errno
  • 返回指针的函数通常返回 NULL 以表示错误
  • c++ STL 函数为“未找到”等状态返回“结束”。使用异常发出信号,例如“内存不足”。

通常,始终如一地使用约定比使用哪种约定更重要。

顺便说一句,如何不这样做的一些例子可以在微软的头文件中找到:

#define S_OK       ((HRESULT)0x00000000L)
#define S_FALSE    ((HRESULT)0x00000001L)

还要注意 Windows 中 's 的两个不同错误值HANDLE:0 或INVALID_HANDLE_VALUE

于 2012-10-04T13:30:04.440 回答
2

我不知道C...

...但在 C++ 中,一般来说,这个想法是不使用错误代码。

我并不是说您应该使用异常,但错误代码并不能提供太多信息(缺少上下文,FILE_NOT_FOUND当文件名未知时有什么价值?)。

在我不使用异常的情况下,我倾向于更喜欢完整的错误对象。一个例子可能是:

boost::variant<File, Error> open(std::string const& filename, FileMode mode);

根据发生的情况,您将在哪里获得文件或错误。

于 2012-10-04T13:21:05.987 回答
1

最好使用 0(零)和非零,因此它们也可以被视为布尔值。通常 false 为 0,而 true 为其他任何值。

于 2012-10-04T13:16:49.903 回答