1

最近,作为我日常工作的一部分,我一直在学习 IBM Rhapsody 并使用它从 UML 生成 C++ 代码。

昨天让我感到震惊的是,考虑为我的 C++ 编译器添加状态机支持可能很酷,所以我在这里记下了一些笔记:http: //ellcc.org/wiki/index.php/State_machines_and_Active_Classes

我这样做的动机是:

  1. 这似乎是一个很酷的主意。
  2. 与当前的 Rhapsody/普通 C++ 编译器相比,该编译器可以进行更好的语义检查(具有更好的错误检查)。
  3. 当编译器本身理解状态机结构时,有许多优化可能性可用。

我可能会尝试将我的语法扩展到除提案之类的内容之外,看看它的效果如何。

您对该提案有何看法?它看起来可读吗?看起来值得吗?


编辑:

感谢您推荐特定库来执行状态机的答案,但这不是我的问题。我已经使用我编写的库和代码实现了许多状态机。

我真的在寻找关于将状态机扩展设计为类 C++ 语言的想法、批评等,而不是这种更改是否适合添加到标准 C++ 中。将其视为特定于域的扩展,我的域是实时控制应用程序。

我已经开始在我的编译器中实现扩展,如下所述:http: //ellcc.org/wiki/index.php/State%5Fmachines%5Fand%5FActive%5FClasses

到目前为止,从提案到实施,这个概念没有太大变化,但在细节上发生了一些变化,我正在完善我对问题语义的理解。

然而,时间会证明整个概念是否有价值。;-)

4

6 回答 6

9

除了少数例外,C++ 传统上使用类库而不是新关键字进行扩展。状态机可以很容易地使用这样的库来实现,所以我认为你的提议没有太大的机会。

我在您的提案中看到的一个问题是使用“goto”进入另一个状态。如果我想在状态转换中在我自己的代码中使用 goto 会发生什么?

于 2009-12-05T14:17:20.707 回答
2

出色的工作发展你所做的事情。像您所做的那样可能是可能的,但我怀疑它是否会进入 C++。大多数将其纳入语言本身的更改只是为了让人们编写更有用和更强大的库。

这里有一个为状态机提供支持的库。我没有尝试过,但它可能会让您感兴趣,并且您可以将您的想法与这样的库结合起来,让其他人使用它。

http://www.boost.org/doc/libs/1_34_1/libs/statechart/doc/index.html

或者,您可以按照您的建议开发自己的扩展,它至少对您有用。Microsoft 实现了一些扩展关键字,因此您没有理由不能创建自己的 C++ 扩展版本。

让新想法不断涌现。

于 2009-12-05T14:27:44.770 回答
2

您应该看看另一位聪明的开发人员如何将状态机支持添加到类似 C 的语言中:UnrealScript 语言参考。请参阅名为“状态”的部分。

UnrealScript 支持语言级别的状态。在 UnrealScript 中,世界上的每个演员总是处于一种且只有一种状态。它的状态反映了它想要执行的动作。例如,移动画笔有几种状态,如“StandOpenTimed”和“BumpOpenTimed”。棋子有几种状态,例如“垂死”、“攻击”和“流浪”。在 UnrealScript 中,您可以编写以特定状态存在的函数和代码。仅当参与者处于该状态时才调用这些函数

于 2009-12-13T17:41:13.810 回答
1

这是一个有趣的想法,但我认为与正式扩展 C++ 相比,为状态机创建自己的特定领域语言实际上会更好。C++ 被设计为一种非常通用的编程语言。我认为 Boost 已经证明 C++ 足够灵活,可以使用库很好地实现大多数功能。它的发展也非常缓慢,以至于到 2009 年标准 C++ 甚至还没有内置的线程支持(计划在 0x 中)。因此,委员会不太可能在一段时间内考虑增加这一内容。

于 2009-12-05T14:23:29.270 回答
1

您的解决方案看起来与基于模板或预处理器宏的解决方案相比没有任何优势。

我也不确定如何提供更好的语义检查。而且我怀疑您是否可以应用许多有用的代码优化。

然而,为了允许更好的优化和语义检查,您还应该用新的关键字(例如)替换“goto” __change__ newState,并且不允许 goto 用于状态更改!像往常一样允许 goto 进行本地跳转。

然后编译器可以提取可能的转换列表。

于 2009-12-13T18:12:02.293 回答
1

阅读您的建议,有以下意见:

  1. 实际上没有关键字来声明和定义一个实际的状态机!您是否假设一个全局状态机(因此是一个全局状态)?这有什么关系__active__

  2. C++ 中最接近的可比结构实际上是枚举。为什么不延长它?

  3. 定义的事件和状态之间似乎存在某种联系,但我看不到它是如何实现的。

  4. 为什么需要线程和计时器?状态机的一些用例可能会从中受益,但一个好的建议应该将它们分开。最重要的是,这应该允许使用标准 C++0x 线程。

就个人而言,我会扩展枚举语法:

enum Foo {
  red, blue, green; /* Standard C++ so far - defines states. State list ends with a ; not a , */ 
  Foo() { *this = red; } // Reuse ctor syntax, instead of __initial__
  ~Foo() { } // reuse dtor syntax, instead of __onexit__

  void Bar() {/**/} // Defines an event, no return value. Doesn't need keyword __event__
};

很自然地,您现在可以在标题中声明您的事件,并在 .cpp 文件中定义它们。我什至不需要在这里建议语法,任何 C++ 程序员都可以在这一点上猜到。为组合状态添加一些继承语法:

enum DrawingObject : public Shape, public Color { /** } // allows (red && circle)

并且您几乎处于您的提案所在的位置,没有任何新的关键字,所有这些都是通过重用已经熟悉的语法来实现的。

于 2009-12-15T15:07:47.743 回答