2016-09-27 67 views
3

我想防止無效值枚舉賦值。我知道,如果我甚至指定的值不是枚舉,它將起作用。例如:如何保護枚舉賦值

enum example_enum 
{ 
    ENUM_VAL0, 
    ENUM_VAL1, 
    ENUM_VAL2, 
    ENUM_VAL3 
}; 

void example_function(void) 
{ 
    enum example_enum the_enum = ENUM_VAL3; // correct 
    the_enum = 41; // will work 
    the_enum = 43; // also will work 
    bar(the_enum); // this function assumes that input parameter is correct 
} 

是否有簡單有效的方法來檢查賦值枚舉是否正確?我可以通過功能

void foo(enum example_enum the_enum) 
{ 
    if (!is_enum(the_enum)) 
    return; 

    // do something with valid enum 
} 

測試值,我可以在下面的方法解決此問題:

static int e_values[] = { ENUM_VAL0, ENUM_VAL1, ENUM_VAL2, ENUM_VAL3 }; 
int is_enum(int input) 
{ 
    for (int i=0;i<4;i++) 
    if (e_values[i] == input) 
     return 1; 
    return 0; 
} 

對於我來說,我的解決方案是低效的,我怎麼可以這樣寫,如果我有更多的枚舉和多個值枚舉?

+0

編譯器警告也許是:功能和struct實現可以從用戶通過在.h文件預先聲明,並在.c文件的執行被藏起來? –

+0

使用斷言。在C中'enum's實際上是'int'。 C不是C++。 – Olaf

回答

1

只要enum是連續的一個可以做這樣的事情:

static int e_values[] = { ENUM_VAL0, ENUM_VAL1, ENUM_VAL2, ENUM_VAL3, ENUM_VAL_COUNT }; 

int is_enum(int input) { return 0 <= input && input < ENUM_VAL_COUNT; } 

另一種方法是不預先驗證枚舉值,但錯誤輸出,一旦代碼檢測到無效值:

switch(input) { 
    case ENUM_VAL0: ... break; 
    case ENUM_VAL1: ... break; 
    ... 
    default: 
     assert(0 && "broken enum"); 
     break; 
} 

但是沒有辦法強制enum的值完全超出C的範圍。如果您想要保護enum以防止擺弄,最好做的就是隱藏值a方式在struct,然後有功能來操縱struct

struct example_t { 
    enum example_enum value; 
} 

void example_set_val0(example_t* v) { v->value = ENUM_VAL0; } 
+0

那麼,我認爲使用'return 0 <= input && input shjeff

1

沒有辦法警告有關分配適合枚舉的整數。

C中的枚舉數是整數類型的同義詞。假設選擇了enum example_enum類型爲int,那麼你的代碼是相同的:

void example_function(void) 
{ 
    int the_enum = ENUM_VAL3; // correct 
    the_enum = 12345; // will work 
    bar(the_enum); // this function assumes that input parameter is correct 
} 

void foo(int the_enum) 
{ 
    if (!is_enum(the_enum)) 
    return; 
    // do something with valid enum 
} 

你可以使用結構,但即使這樣,可以規避:

struct example_enum_struct e = { 12345 }; 
e.value = 23456; 

基本上,如果你想限制一個類型到特定的值,您將需要執行檢查。