2012-12-31 80 views
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 

輸出:用法:咖啡--help --version

./sample --version 

輸出


我很困惑,爲什麼--version沒有輸出字符串alpha

+5

一個很好的樣本,以證明爲什麼它能夠更好地使用一個函數的定義,而不是一個宏觀的。 –

+2

http://www.parashift.com/c++-faq/macros-with-multi-stmts.html – aschepler

回答

6

std::cout << x << std::endl ; exit(-1)由宏preoprocessor在這兩條線

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 -Ecl -E來獲取C預處理器的輸出,以便您可以看到編譯器實際看到的內容。

編輯:我應該指出,在這種情況下,personnaly寧願選擇「die(msg)函數」而不是固定宏。然後,你可以在die()中設置一個breakpoing,並找出當某些工作不正常時你是如何到達那裏的!你不能在宏中設置一個斷點。

+1

我知道'do {} while(0)'技巧,但不記得爲什麼'{ ''是不夠的。這是爲什麼? – configurator

+0

@configurator:對於多行「if」塊,「{}」不足以滿足相同的原因。或任何塊。 –

+0

@LightnessRacesinOrbit:嗯? – configurator

0

剛剛嘗試慘遭替換宏的身體,你就會明白爲什麼:

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

變爲:

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

隨着對if聲明沒有括號{ },身體剛做的一條指令,因此總是執行exit(-1)

你會發現,如果通過使用if/else if而不是夫婦,因爲第二個else if將錯過其父母。

+1

哈哈「殘酷」=) –

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); 
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);