2013-08-20 59 views
0

我工作的一个有限状态机库,这些公共方法:声明,异常,运行时错误或未定义行为?

template <typename STATE_T> 
void add_state();    // allocate STATE_T on heap - STATE_T must derive from state 

template <typename FROM_STATE_T, typename TO_STATE_T> 
void link_state(std::function<bool()> cond, unsigned int priority); 

// search for base state pointer that can be dynamically caste d to STATE_T* type, set this state as the beginning state 
template <typename STATE_T> 
void begin_state(); 

void execute(); 

//STATE_T must be a user defined state class that inherits from the base state class. 

我选择在编译时运行时实现,因为使用可变参数模板参数的状态时,界面会更复杂。但是,我想强制实施一些限制,以确保程序员在实现状态机时不会引入错误。

这里有限制,我想执行:

  1. 不能添加重复的状态
  2. 无法链接不存在的状态(如状态类型(即增加了两个相同的派生型。)没有国家的FSM列表)
  3. 国家必须有一个入口点/可到达
  4. 一个开始和结束时的必须存在
  5. 执行不能同时运行多次

声明中止程序并明确遵守这些约束,但它是正确的选择吗?

可能违反了1,2,3并且fsm仍然处于有效状态(根本不做任何事情),但我不喜欢隐式处理这些问题的想法,因为它引入了虚假的安全感隐藏程序员错误。

如果我为1,2,3引发异常并且程序员捕获它们,那么fsm仍然可以处于有效状态,从而允许运行不正常的fsm。

5是不应该做的事情。我应该处理这个问题,还是把它作为UB?

什么是最适合这些约束的机制?

回答

2

这是一个相当典型的处理错误的问题。答案通常取决于成本。这个问题的成本是什么被忽视?程序异常终止的成本是多少?

在大多数情况下,程序崩溃的代价并不是很大。用户将重新启动它。在这种情况下,你应该去处理未处理的异常。这样,你会注意到这些bug很快,修复它们,最终得到一个更好的程序。有一种混合方法:在DEBUG构建中,通过“断言失败”消息框(通常这是用ASSERT()宏)来处理错误,但是在发布版本中,静静地处理错误。然而,这会让问题在客户端的计算机上不被注意,往往会引发其他错误,这些错误很难找到。

最后,关于程序员可以处理异常的担忧:这不是你应该考虑的问题。你指出了一个致命的错误,如果程序员忽略它,那是他的错。

相关问题