字符串转换错误:异常还是错误代码
String conversion errors: exceptions or error codes?
在编写一个函数以在不同编码的字符串之间转换(例如从UTF-8到UTF-16)时,处理错误(例如无效的输入UTF-8字节序列)的最佳方法是什么?是否引发异常或返回错误代码(甚至是bool
)?
// Throws a C++ exception on error.
std::wstring ConvertFromUtf8ToUtf16(const std::string& utf8);
// Returns true on success, false on error.
bool ConvertFromUtf8ToUtf16(std::wstring& utf16, const std::string& utf8);
使用异常,可以进行链式函数调用(当函数返回值用作其他函数/方法的输入时)。
但我不确定在这种情况下使用异常是否好;我在想Eric Lippert在他的高质量博客文章中所说的令人烦恼的异常(以及相关的Int32.Parse()/TryParse()
示例)。
例如,如果使用异常,则应强制调用方将函数调用包装在try/catch
块中,以检查UTF-8输入无效的情况:
try
{
wstring utf16 = ConvertFromUtf8ToUtf16(utf8);
}
catch(const Utf8ConversionException& e)
{
// Bad UTF-8 byte sequence
...
}
这对我来说似乎并不理想。
也许最好的做法是只提供两个重载(在非抛出重载中实现转换代码,在抛出重载中只调用非抛出版本,在出现错误时返回代码抛出异常)?
一条准则是考虑如果用户忽略或不知道他们应该检查返回的错误代码会发生什么。
- 如果代码理论上可以在出现错误时继续,则返回错误可能被认为是合理的。正如您所提到的,代码看起来更干净
- 如果忽略错误可能会导致以后出现非常糟糕的行为,那么抛出异常可能是更好的主意
-
在一定程度上平衡错误代码的简洁性和迫使程序员意识到潜在错误的第三个潜在选择是使函数需要引用错误代码。这在导出的库和不能有效处理异常的(大多数是旧的)编译器中也能很好地工作。
StringConversionResult result; // Could be a "success" bool
wstring utf16 = ConvertFromUtf8ToUtf16(utf8, result);
如果此函数是从库导出的,请使用返回代码。当库和客户端使用不同的C/C++运行库构建时,从导出的函数引发异常可能会导致程序崩溃。一般来说,这是未定义的行为。
对于内部使用,我相信exception是一个更好的选择。您所说的情况是,当调用者不使用catch块时,程序会立即崩溃(未处理的异常)。这样做会更好,然后在将来的某个时间点继续执行程序并得到未定义的结果。
只有三种选择。第一个是"用错误代码点替换所有失败"-Unicode标准提供了几个替换代码点。这在某些情况下是可以的。第二种是抛出异常。第三个是提供一个错误函数对象,在失败时调用。例如,
bool fail = false;
std::u16string str = ConvertFromUTF8ToUTF16(utf8, [&] {
return u16"default";
// or
throw std::runtime_error("fail");
// or
fail = true;
});
关键是,在任何情况下,你都不依赖用户来检查失败——如果他什么都不做,那么要么他的函数不继续,编译器会哭,要么函数可以继续。
返回错误代码不是一种选择——这非常容易出错。
- 错误处理.将系统错误代码映射到泛型
- 为什么我在使用void函数时得到错误代码C2276
- 尝试链接我的着色器时,我收到错误代码"error c5145 must write to gl_position"
- 如何将strftime中的格式错误作为异常捕获
- 逻辑运算符上出现错误代码 a')'
- 'val' Arduino 错误代码之前的预期'('
- 我在贪吃蛇游戏中收到了错误代码 -1073741571
- 根据 GetLastError 直接写入磁盘会导致错误代码 5
- 当我选择大于 720 的矩阵大小时,程序退出并显示错误代码.可能是什么原因?
- 创建进程 API 失败,在窗口 122 上出现错误代码 10
- 使用另一个函数调用一个函数(都在类中)时出现问题.没有错误代码C++
- 如何正确解包来自提升异常的错误代码
- STL 中是否有任何错误代码异常
- 结合基于异常和错误代码的类实现
- 字符串转换错误:异常还是错误代码
- 将错误代码批量转换为异常
- c++错误代码与断言与异常的选择
- 使用异常处理库的(可能更改的)错误代码
- 异常和错误代码:以正确的方式混合它们
- 错误处理范例:混合异常和错误代码