宏扩展&代码生成有优点&缺点。你最喜欢的方法是什么?为什么?我们应该什么时候选择一个呢?请提供建议。谢谢!C/C++宏扩展与代码生成
宏扩展可以非常方便&有所帮助: http://dtemplatelib.sourceforge.net/table.htm
VS
虽然代码生成为您提供了大量的漂亮的代码: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/
宏扩展&代码生成有优点&缺点。你最喜欢的方法是什么?为什么?我们应该什么时候选择一个呢?请提供建议。谢谢!C/C++宏扩展与代码生成
宏扩展可以非常方便&有所帮助: http://dtemplatelib.sourceforge.net/table.htm
VS
虽然代码生成为您提供了大量的漂亮的代码: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/
这是一个权衡额外的好处。让我举个例子。我在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#解析器,所以我必须手工完成代码生成。这是一种皇室般的痛苦,但与通常的编码方式相比,它仍然值得。
在C或C++中,宏扩展为臭名昭着的难以调试。另一方面,编写代码生成器更容易调试,因为它本身就是一个单独的程序。
但是,您应该知道,这仅仅是C预处理器的限制。例如,在Lisp系列语言中,宏扩展是代码生成,它们完全一样。要编写一个宏,你需要编写一个程序(在Lisp中)来将S表达式输入转换为另一个S表达式,然后将其传递给编译器。
感谢您的回复,Greg。编写一个体面的代码生成器需要花费更多的时间,并且宏看起来像是一件快速的黑客工作。 – Viet 2009-11-27 09:48:53
++我的情绪正好。如果有一种方法可以逐步完成预处理,那将会很好。即便如此,如果代码生成足够简单,我更喜欢宏。 – 2009-11-30 15:48:05
对于C++,我更喜欢模板元编程或通过宏代码生成,但宏仍然有其用处。
您与dbtemplatelib给出的例子可以用的C++ 0x Variadic Templates覆盖,有喜欢的类型检查等
感谢您的建议。模板也有其优点。可变参数宏在那里,但可变参数模板尚未流行,因为C++ 0x仍然是新的。 – Viet 2009-11-27 09:55:58
嗯,确切地说,它还没有出来,它将会是一个“C++ 1x”。但可变参数模板在某些编译器中实现,例如,要使用它们与gcc,必须添加“-std = C++ 0x”作为编译器开关。 – hirschhornsalz 2009-11-27 14:19:19
+1谢谢迈克。这是最好的答案:) – Viet 2009-12-01 07:31:24