【问题标题】:Code generation using preprocessor macros使用预处理器宏生成代码
【发布时间】:2018-01-03 06:41:59
【问题描述】:

最近,我在一个项目中工作,其中有很多使用宏生成的代码。我遇到过这样的情况,生成的代码非常少。但是在当前这个版本中,有很多代码是使用 #defines 等生成的。 示例,例如用于事件生成和处理的类以及为类生成类 Id。

#define INIT_EVENT_INFO(eventType) \
   template <> const GenericClassID eventType::tClassID(#eventType) ;

#define DECLARE_EVENT(dType, evtType, destnType) \
   typedef DUMMY_EVT_GEN<dType, std_event, custom_destn, destnType>::EventClass evtType;

template <typename ctData,
          EventTypes evType,
          DestnTypes evtDestType = standard_destn,
          class DestnInterface = EmptyClass>
class DUMMY_EVT_GEN
{
private:
   // alias for our current generator
   typedef DUMMY_EVT_GEN<ctData,
                              evType,
                              evtDestType,
                              DestnInterface> Generator;

   // Construct the first layer by adding the data part to our
   // framework event base class.
   //
   typedef BaseEvent::DerivedEvent<Generator> CompleteEvent_;


   /*
    * Assemble an event destn type
    */

   // Determine base class for event Destn: RTTIEventDestn for
   // rtiDestns
   typedef typename IF<isRtiDestn, BRTTIEventDestn, EventDestn>::type DestnBase_;

   // create event Destn type
   typedef typename IF<isCustomDestn, DestnInterface, BaseEvent::THBDestn<Generator> >::type DestnType_;

public:

   /**
    * A struct that contains all configuration options 
    */
   struct Config
   {
      /// base class for the Destn (rti or not)
      typedef DestnBase_  DestnBaseClass;
      /// class serving as data container for the event type
      typedef ctData     EventDataClass;

      /// the resulting event type
      typedef CompleteEvent_ EventClass;
      /// the resulting Destn interface type
      typedef DestnType_  DestnInterface;
   };

   // our final return values
   typedef typename Config::EventClass EVT;
   typedef typename Config::DestnInterface DestnInterface;
   typedef typename Config::EventClass EventClass;
};

现在,我的问题是,有没有一种特定的方式已经定义了这些东西。

哈希定义可以随意使用。 但是,是否有任何定义的模式或方法来编写这样的代码,这有助于我们生成这样的代码。不仅是这种情况。还有许多其他场景,可以编写此类代码并将其用于自动生成类、事件、结构等。

作为一名程序员,如何考虑编写这样的宏来减轻我们的工作量。它确实来自实践,但是否有任何特定的方式或模式 或任何帮助我们以这种方式编程的文档,我的意思是考虑使用此类宏进行编程。

任何指示或建议都会有很大帮助。

【问题讨论】:

  • 对于 C++,有提供此功能的 boost。如果你真的对 C 的那个感兴趣,你可以看看我的包 P99。
  • 在这种特殊情况下,宏用于污染代码:-(。没有它们,程序会更好。尽管在其他情况下使用宏有充分的理由。

标签: c++ class macros code-generation


【解决方案1】:

这只是我的想法,不适合简单的回复:-)。 C++,特别是 c11 及更高版本添加了许多功能,以用可控的基于编译器的生成器替换宏,从模板开始,以 constexpr 结束。这是一个比宏更强大的机制,尽管它通常需要更多的文本来表达意图。无论如何,由于这个原因,与c 相比,对宏的需求显着减少。我实际上看到了将它们与 c++ 一起使用的 3 个充分理由

  1. 在语言中隐藏特定于实现的细节。即 gcc 中的函数或结构属性,可能无法在其他编译器中实现或以不同方式实现。 #define PACKED __attribute((packed))__
  2. 出于不同原因使用条件编译,例如头文件中的保护宏:#ifndef MY_HDR .. #define MY_HDR ... #endif
  3. 方便宏,替换相对较大的重复代码块,这些代码不适合函数,特别是当您需要将某些内容转换为字符串时。即#define tostr(A) case A: return #A;

【讨论】:

  • 感谢浪涌的回答。我绝对得到了使用这些宏的好处。但是是否有任何特定的模式或任何明确的宏编码或使用指南可以帮助学习这种编码风格并将其应用到其他地方。我也在 Windows 事件生成机制中看到过这样的代码。但是这里的大部分代码都是使用这样的宏生成的。我只是想知道在什么情况下应该使用这样的宏,是否有任何特定的模式可以遵循。
  • 建议是:除非您绝对需要宏,否则不要使用宏。不确定是否有更好的指南:-)。您可能会找到一些特定于组织的指南,但没有全行业的指南。我想每个人都同意(或多或少)的唯一事情是宏的大写名称。其余的都是个人的。
  • 感谢您的投入。
  • 我讨厌宏和模板的地方在于,当显示在多个地方实例化的代码时,这些工具经常会中断,并且没有解决方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
  • 2017-01-31
相关资源
最近更新 更多