0

C++ を学習していますが、マクロの動作が期待どおりではありません。

  1     #include<cstdlib>
  2     #include<iostream>
  3     #include<cstring>
  4     #define die(x) std::cout << x << std::endl ; exit(-1) 
  5     const char *help = "Usage: coffee --help --version";
  6     const char *version = "alpha";
  7     int main(int argc,char **argv)
  8     {
  9               if(argc<2||!strcmp(argv[1],"--help"))
 10                       die(help);
 11               if(!strcmp(argv[1],"--version"))
 12                       die(version);
 13 
 14               return 0;
 15               
 16     }

g++ -o sample ./*
./sample --help

出力:使用法: coffee --help --version

./sample --version  

出力:


--versionstring を出力しなかった理由がわかりませんalpha

4

4 に答える 4

6

std::cout << x << std::endl ; exit(-1)これらの2行でマクロプリプロセッサによって展開されるとき

 9               if(argc<2||!strcmp(argv[1],"--help"))
 10                       die(help);

結果のコードは次のとおりです。

 if(argc<2||!strcmp(argv[1],"--help"))
       std::cout << help << std::endl; 
 exit(-1); 

これはおそらくあなたが望んでいたものではありません。

「マルチステートメントマクロ」の一般的なトリックは、マクロに含めるdo { ... } while(0)ステートメントを回避することです。

gcc -Eまたはを使用cl -EしてCプリプロセッサからの出力を取得できるため、コンパイラが実際に何を認識しているかを確認できます。

編集:私は個人的に、この場合、マクロを修正するよりも「die(msg)関数」を好むことを指摘する必要があります。次に、たとえば、die()にブレークポイントを設定して、何かが正しく機能していないときにどのようにしてそこに到達したかを調べることができます。マクロにブレークポイントを設定することはできません。

于 2012-12-31T13:48:41.613 に答える
0

マクロの本体を残酷に置き換えてみてください。理由がわかります。

if(argc<2||!strcmp(argv[1],"--help"))
  die(help);

になります:

if(argc<2||!strcmp(argv[1],"--help"))
  std::cout << help << std::endl;
exit(-1);

ステートメントに中括弧{ }がない場合、本文は1つの命令だけで構成されているため、は常に実行されます。ifexit(-1)

if / else if代わりにそれを使用して、2番目がその親を逃したif / ifのでカップルするかどうかを発見したでしょう。else if

于 2012-12-31T13:48:55.483 に答える
0

あなたは忘れ{ }ました。マクロを手動で展開すると、結果が表示されます。

if(argc<2||!strcmp(argv[1],"--help"))
   std::cout << help << std::endl ; exit(-1);

すなわち

if(argc<2||!strcmp(argv[1],"--help"))
   std::cout << help << std::endl ;
exit(-1);
于 2012-12-31T13:49:12.300 に答える
0

マクロ置換後のコード

if(argc<2||!strcmp(argv[1],"--help"))
   std::cout << help << std::endl ; exit(-1) ;  //<-- this exit will work always.
if(!strcmp(argv[1],"--version"))
   std::cout << version << std::endl ; exit(-1) ;

正しい方法:

#define die(x) do {std::cout << x << std::endl ; exit(-1); } while(false);
于 2012-12-31T13:50:25.970 に答える