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/

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top