【问题标题】:C/C++ Macro expansion vs. Code generationC/C++ 宏扩展与代码生成
【发布时间】:2010-12-20 22:14:15
【问题描述】:

宏扩展和代码生成都有利有弊。你最喜欢的方法是什么,为什么?我们什么时候应该选择一个而不是另一个?请多多指教。谢谢!

宏扩展非常方便和有用: http://dtemplatelib.sourceforge.net/table.htm

虽然代码生成为您提供了很多不错的代码: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

【问题讨论】:

    标签: c++ code-generation macros


    【解决方案1】:

    对于 c++,我更喜欢模板元编程或代码生成而不是宏,但宏仍有其用途。

    您使用 dbtemplatelib 给出的示例可以用 c++0x Variadic Templates 覆盖,并具有类型检查等额外好处。

    【讨论】:

    • 感谢您的建议。模板也有其优点。可变参数宏已经存在,但可变参数模板尚未流行,因为 C++0x 仍然是新的。
    • 嗯,确切地说,它还没有出来,它会是一个“c++1x”。但是在一些编译器中实现了可变参数模板,例如,要将它们与 gcc 一起使用,您必须添加“-std=c++0x”作为编译器开关。
    【解决方案2】:

    在 C 或 C++ 中,宏扩展是出了名的难以调试。另一方面,编写代码生成器更容易调试,因为它本身就是一个单独的程序。

    但是,您应该知道这仅仅是 C 预处理器的限制。例如,在 Lisp 语言家族中,宏扩展代码生成,它们是完全一样的。要编写宏,您需要编写一个程序(在 Lisp 中)将 S 表达式输入转换为另一个 S 表达式,然后将其传递给编译器。

    【讨论】:

    • 感谢您的回复,格雷格。编写一个像样的代码生成器需要更多时间,而宏看起来像是完成工作的快速技巧。
    • ++ 完全是我的观点。如果有一种方法可以逐步完成预处理,那就太好了。即便如此,如果代码生成足够简单,我还是更喜欢宏。
    【解决方案3】:

    两者都有自己的问题。与宏不同,代码生成可以生成可读且可调试(甚至是一个词吗?)的代码,但它的灵活性较低且更难更改。

    【讨论】:

      【解决方案4】:

      这是一个权衡。让我举个例子。我在 1985 年左右偶然发现了 differential execution 的技术,我认为它是一个非常好的用户界面编程工具。基本上,它需要像这样的简单结构化程序:

      void Foo(..args..){
        x = y;
        if (..some test..){
          Bar(arg1, ...)
        }
        while(..another test..){
          ...
        }
        ...
      }
      

      然后使用这样的控制结构:

      void deFoo(..args..){
        if (mode & 1){x = y;}
        {int svmode = mode; if (deIf(..some test..)){
          deBar(((mode & 1) arg1 : 0), ...)
        } mode = svmode;}
        {int svmode = mode; while(deIf(..another test..)){
          ...
        } mode = svmode;}
        ...
      }
      

      现在,一个非常好的方法是为 C 或任何基础语言编写解析器,然后遍历解析树,生成我想要的代码。 (当我在 Lisp 中完成时,这部分很容易。)

      但谁愿意为 C、C++ 或其他语言编写解析器?

      所以,我只是编写宏,这样我就可以编写如下代码:

      void deFoo(..args..){
        PROTECT(x = y);
        IF(..some test..)
          deBar(PROTECT(arg1), ...)
        END
        WHILE(..another test..)
          ...
        END
        ...
      }
      

      但是,当我在 C# 中执行此操作时,有些人认为宏不好,我不想编写 C# 解析器,所以我必须手动生成代码。这是一种皇家的痛苦,但与通常的编码方式相比,它仍然是值得的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        相关资源
        最近更新 更多