2014-10-09 54 views
2

通常,預處理器宏用於控制某些代碼組是否被編譯。這是一個例子。如何用if語句替換預處理器宏?

#define ENABLE 1 

void testswitch(int type){ 

    switch(type){ 
    case 1: 
     std::cout << "the value is 1" << endl; 
     break; 
    case 2: 
     std::cout << "the value is 2" << endl; 
     break; 
#ifdef ENABLE 
    case 3: 
     std::cout << "the value is 3" << endl; 
     break; 
    case 4: 
     std::cout << "the value is 4" << endl; 
    } 
#endif 
    } 
} 

現在我想刪除所有這些預處理宏與if條件

void testswitch(int type, bool enable){ 
    switch(type){ 
    case 1: 
     std::cout << "the value is 1" << endl; 
     break; 
    case 2: 
     std::cout << "the value is 2" << endl; 
     break; 
    if (enable) { 
    case 3: 
     std::cout << "the value is 3" << endl; 
     break; 
    case 4: 
     std::cout << "the value is 4" << endl; 
    } 
    } 
} 

取代它們。然而,上面的代碼並沒有像以前那樣具有相同的邏輯。無論變量enable是否爲truefalsecase 3case 4始終啓用。這些代碼在VS2010下進行測試。

Q1:編譯器是否忽略if條件?

爲了實現我的目標,我必須要改變這些代碼如下:

void testswitch(int type, bool enable){ 
    switch(type){ 
    case 1: 
     std::cout << "the value is 1" << endl; 
     break; 
    case 2: 
     std::cout << "the value is 2" << endl; 
     break; 
    case 3: 
     if (enable) 
      std::cout << "the value is 3" << endl; 
     break; 
    case 4: 
     if (enable) 
      std::cout << "the value is 4" << endl; 
    } 
} 

但似乎有在代碼冗餘if有沒有更好的方法來做到這一點?

+0

1語法是完全錯誤的。第二種方法值得懷疑,因爲建議不要使用'#ifdef',結果是非常不同的。 – 2014-10-09 06:56:45

+0

由於第一種語法錯誤,爲什麼代碼可以在VS中成功構建?我可以考慮這是VS2010中的一個錯誤嗎? – zangw 2014-10-09 07:05:52

+3

@zangw從「這是一個語法錯誤」的意義上來說,語法沒有錯,但是在「它甚至不能完成你想要的東西」這個意義上。 – Angew 2014-10-09 07:11:59

回答

2

編譯器不忽略if條件。但是你必須記住case標籤是標籤。switch只是goto更有組織的方法。由於goto可以跳到由if(或循環或任何其他)控制的塊中,所以可以跳到switch

你可以把enable -only案件在一個單獨的開關:

void testswitch(int type, bool enable) { 
    switch(type) { 
    case 1: 
    std::cout << "the value is 1" << endl; 
    break; 
    case 2: 
    std::cout << "the value is 2" << endl; 
    break; 
    default: 
    if (enable) { 
     switch(type) { 
     case 3: 
     std::cout << "the value is 3" << endl; 
     break; 
     case 4: 
     std::cout << "the value is 4" << endl; 
     break; 
     } 
    } 
    break; 
    } 
} 
+0

+1:你的解決方案與我的類似,但效率更高。 – 2014-10-09 07:12:05

+1

@PaulR是的,我從你的解決方案中獲得了一些靈感,然後稍微提前一點,所以我給了你一個補償:-) – Angew 2014-10-09 07:13:31

+2

關鍵是類似於goto。實際上有一些(非常罕見)的情況是非常有用的(除了混淆之外的原因)。 – 2014-10-09 08:34:30

0

如果enable是一個常數(或在編譯時間,否則已知的),合理的智能編譯器(如GCC)將不生成代碼來檢查的enable值,但是將不會生成代碼(如果它是已知的是假的),否則產生當時的陳述。其他

1

一種解決方案是重構這個成兩個switch語句,與由if (enable)被控制的第二個:

void testswitch(int type, bool enable) { 
    switch(type) { 
     case 1: 
      std::cout << "the value is 1" << endl; 
      break; 
     case 2: 
      std::cout << "the value is 2" << endl; 
      break; 
     default: 
      break; 
    } 
    if (enable) { 
     switch(type) { 
      case 3: 
       std::cout << "the value is 3" << endl; 
       break; 
      case 4: 
       std::cout << "the value is 4" << endl; 
       break; 
      default: 
       break; 
     } 
    } 
}