2013-01-14 46 views
0

我正在编写一个C++代码,用于控制一个特殊设备,它是多个SDK的融合体。我的代码看起来像用于程序硬件编程的错误处理技术

#define sdk1SafeCall(err) __sdk1SafeCall(err,__FILE__,__LINE__) 

int errorcode = 0; 
sdk1SafeCall(sdk1_InitializeDevice()); 
errorcode=sdk2_InitializeDevice(); 
errorcode=sdk3_InitializeDevice(); 

if (some_parameter) 
{ 
    errorcode=sdk2_readDevice(true); 
} 
else 
{ 
    errorcode=sdk3_writeDevice(); 
} 
label again: errorcode=sdk1_readDevice(); 
if (error) goto again; 

errorcode=close_everything(); 

使用参数将重新安排控制流。我当前的方法使用类似cudaSafeCall来包装错误代码并退出。我不知道该怎么做的是在哪里存储这些错误的详细解释或如何从它们中恢复(如goto示例)。在一天结束时,代码看起来非常混乱。

编辑

我有时会处理与包装的错误。

+0

无论如何,你实际上从来没有真正阅读过错误代码的价值,所以你可以不用打扰它,并用更清晰的代码实现相同的破坏实现。 –

+0

@PeteFordham我不知道如何处理他们。在我的实际实现中,我使用了'sdk1SafeCall(sdk1_readData())',它可以像在CUDA中一样打印一个数字,一个'__FILE__'和'__LINE__'。 – Mikhail

回答

1

写错误安全代码很难。在你的伪代码中,你根本没有处理错误。 errorcode只会产生“close_everything()”的结果 - 即使其他所有事情都出错了,它也可能成功。

解决这样的事情在C++中的典型方法是为每个“资源”(如“设备”)的对象,并throwexception如果出现问题,你不要指望从恢复。在try/catch区块中包裹整个功能[或外部功能组]。当然,如果“失败是正常的”(例如,您尝试从网络端口读取,并且由于没有可用的数据而导致超时,那么您不应该抛出异常)。这应该使用返回值。

请注意,使用对象来处理资源需要仔细设计代码,特别是您的析构函数在清理异常后执行清理工作时会做得很好。如果您在构造函数中抛出异常,请确保不要遗漏任何东西 - 这就是您如何得到泄漏。当然,还有很多其他解决方案 - 毕竟,我们正在谈论编程,所以总有至少11种不同的方式来解决问题。

+0

有没有解决某些问题的C++ 11方法? – Mikhail

+0

上面我描述的是通用C++方法 - 我不认为C++ 11在这里提供了很多帮助 - 它仍然是“如果出现错误,抛出异常,然后出现在某处几个呼叫级别下降,赶上那个例外“。为了充分解释它,你需要许多页面的文本,我很抱歉,但你的任务是在网络上搜索这些解释 - 他们在那里 - 或者购买一本描述如何以安全方式编写C++的书。如果你有特定的问题,我很乐意回答,但我不会解释所有关于如何做到这一点的信息...... –

+0

我应该补充一点,这一切都取决于你想要做什么以防万一出现错误 - “简单”选择是打印消息并退出。但这并不总是一个好的选择。如果“退出并打印消息”对您来说是个不错的选择,那么使用宏或函数来检查错误是另一种选择。 –