C/C ++ Macro expansão vs. geração de código
-
05-07-2019 - |
Pergunta
Tanto a expansão macro quanto a geração de código têm prós e contras. Qual é a sua abordagem favorita e por quê? Quando devemos escolher um sobre o outro? Por favor, avise. Obrigada!
A expansão macro pode ser muito útil e útil:http://dtemplatelib.sourceforge.net/table.htm
vs.
Enquanto a geração de código fornece bastante código legal:http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/
Solução
É uma troca. Deixe -me dar um exemplo. Eu tropecei na técnica de execução diferencial Por volta de 1985, e acho que é uma ferramenta muito boa para programar interfaces de usuário. Basicamente, são necessários programas estruturados simples como este:
void Foo(..args..){
x = y;
if (..some test..){
Bar(arg1, ...)
}
while(..another test..){
...
}
...
}
e rucks com a estrutura de controle como esta:
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;}
...
}
Agora, uma maneira muito boa de fazer isso seria escrever um analisador para C ou qualquer que seja o idioma base e, em seguida, caminhar pela broca, gerando o código que eu quero. (Quando eu fiz isso em Lisp, essa parte foi fácil.)
Mas quem quer escrever um analisador para C, C ++ ou o que for?
Então, em vez disso, apenas escrevo macros para que eu possa escrever o código como este:
void deFoo(..args..){
PROTECT(x = y);
IF(..some test..)
deBar(PROTECT(arg1), ...)
END
WHILE(..another test..)
...
END
...
}
No entanto, quando faço isso em C#, alguém em sua sabedoria decidiu que as macros eram ruins e não quero escrever um analisador C#, então tenho que fazer a geração de código manualmente. Isso é uma dor real, mas ainda vale a pena em comparação com a maneira usual de codificar essas coisas.
Outras dicas
Para C ++, prefiro metaprogramação de modelo ou geração de código em vez de macros, mas as macros ainda têm seus usos.
O exemplo que você deu com dbtemblatelib pode ser coberto com C ++ 0x Modelos variádicos, com benefícios adicionais como verificação de tipo etc.
Em C ou C ++, a expansão macro é notoriamente difícil de depurar. Por outro lado, escrever um gerador de código é mais fácil de depurar, porque é um programa separado em si.
No entanto, você deve estar ciente de que isso é apenas uma limitação do pré -processador C. Por exemplo, na família de idiomas Lisp, a expansão macro é Geração de código, eles são exatamente a mesma coisa. Para escrever uma macro, você escreve um programa (no LISP) para transformar a entrada de expressão S em outra expressão S, que é passada para o compilador.
Ambos têm seus problemas. Diferentemente das macros, a geração de código pode produzir um código legível e de debatível (é mesmo uma palavra?), Mas é menos flexível e mais difícil de alterar.