2012-12-28 62 views

回答

37

switch標籤必須是常量表達式,它們必須在編譯時進行評估。如果要在運行時值上分支,則必須使用if

A const限定變量不是常量表達式,它只是一個值,你不允許修改。

整數常量表達式的形式在6.6(6)C99和C2011標準的n1570草案]詳述:

6 An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.

的限制,只有sizeof表達式,其結果是一個整常數,允許排除sizeof其操作數是可變長度數組的表達式。

+1

感謝明確的答案,我會使用相反,如果。 –

+0

好吧,'const'不是一個整型常量表達式,但是'static const'呢? – Cyan

+0

@Cyan不在C(最後我看了)。在其他語言中,事情可能會不同,。 –

5

在C.全部case標籤必須是編譯時間常數。在C中,const限定符不會創建編譯時常量,它只是指定運行時變量是隻讀的。

A switch不適合您正在嘗試做的事情。

0

在C中,變量不能用在switch case標籤中,而只能在那裏使用常量表達式。

5

讓我來舉個例子。以下是對gcc版本4.6.3測試與標誌-std=c99 -pedantic集:

#define SOME_HARDCODED_CONSTANT 0 //good 
int foo(int i, int b){ 
    const int c=0; //bad 
    int a=0; //bad 

    switch(i){ 
     case c:  //compile error 
     case a:  //compile error. 
     case (b+a): //compile error 
     case SOME_HARDCODED_CONSTANT: //all good 
     case 5: //all good 
    } 
} 

正如其他人指出,case參數不能在運行時進行評估。使用if-else塊來做到這一點。

+0

顯然是最好的答案。謝謝。 – Noel

0

在OSX上,clang似乎將常量作爲案例標籤而沒有投訴。

#include <stdio.h> 

#define SOME_HARDCODED_CONSTANT 0 //good for sure 
int foo(int i, int b){ 
    const int c=1; //no problem!!! 

    switch(i){ 
     case SOME_HARDCODED_CONSTANT: //all good 
      printf("case SOME_HARDCODED_CONSTANT\n"); break; 
     case c:  //no compile error for clang 
      printf("case c\n"); break; 
     case 5: //all good 
      printf("case 5\n"); break; 
    } 
    return i+b; 
} 

int main() { 
    printf("test foo(1,3): %d\n", foo(1,3)); 
} 

輸出:

$> cc test.c -o test; ./test 
case c 
test foo(1,3): 4 
+0

如果你問它:'caseconst.c:10:14:warning:它不會抱怨,表達式不是一個整型常量表達式; 將它摺疊爲常量是一個GNU擴展[-Wgnu-folding-constant]'。在這裏,'const int c = 1;'讓編譯器在編譯時知道該值(作爲一個整型常量表達式),因此它有可能將'c'視爲'switch中的一個整型常量表達式'。如果通過函數調用初始化'c',則會出現編譯錯誤。 –

+0

您可以使用不同的版本。我的cc沒有投訴,並且報告如下。 $> cc --version $> Apple LLVM 6.0版(clang-600.0.57)(基於LLVM 3.5svn) $>目標:x86_64-apple-darwin14.3.0 – Farley

+0

是的,不同的版本。然而,當你要求它是挑剔的時候,它必須警告,'-std = c11 -Weverything'必須告訴你,'-WgnU-folding-constant','-pedantic-errors'必須導致編譯錯誤。但是由於這是一件相當無害的事情,所以在提到它之前,你需要告訴編譯器真的很挑剔。 –