2013-04-02 39 views
11

Tôi có một số mã tôi đang chuyển sang một nền tảng mới, và nó bắt đầu cho tôi một lỗi về việc so sánh hai điều tra viên từ hai danh sách liệt kê khác nhau. Tôi lúng túng tại sao nó lại cho tôi một lỗi về điều này. phầnTại sao tôi gặp lỗi khi so sánh trực tiếp hai enums?

Việc liệt kê một specificers của spec C (6.7.2.2) khẳng định:

The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted.127) An enumerator with = defines its enumeration constant as the value of the constant expression. If the first enumerator has no =, the value of its enumeration constant is 0.

Vì vậy, tôi sẽ có thể sử dụng các thành viên enum giống như int hằng số. Trong chương trình mẫu nhỏ này:

enum first { 
    a, 
    b 
}; 

enum second { 
c, 
d 
}; 

int main(){ 
    enum first myf = a; 
    enum second mys = c; 

    if(myf == mys) 
     printf("same value\n"); 
    return 0; 
} 

Khi biên soạn với gcc -Wall -Werror Tôi nhận được thông báo:

error: comparison between ‘enum first’ and ‘enum second’ [-Werror=enum-compare]

Tôi biết rằng nếu tôi định kiểu cả myfmys như int s trình biên dịch sẽ được hạnh phúc, giống như Tôi có thể đặt một vài số int s với các giá trị từ myfmys và thực hiện so sánh; nhưng tại sao tôi phải làm hoặc trong số này để loại bỏ cảnh báo? Tại sao cảnh báo này lại tồn tại ở nơi đầu tiên? Phải có một số nguy hiểm khi làm điều này mà tôi không thấy.


LƯU Ý:
Tôi đã đọc các tài liệu hướng dẫn gcc trên enum-so sánh cờ này, nhưng nó không nói nhiều về bất cứ điều gì:

-Wenum-compare
Warn about a comparison between values of different enumerated types. In C++ enumeral mismatches in conditional expressions are also diagnosed and the warning is enabled by default. In C this warning is enabled by -Wall.

+2

Tài liệu gcc khá dễ hiểu. Điều gì không rõ ràng ở đó? – SomeWittyUsername

+1

@icepack - * cách * giải thích đó? Nó nói những gì nó làm, nó không nói một từ về ** tại sao ** bất cứ ai sẽ cần điều đó. Nếu các thành viên của hai enums khác nhau là cả hai loại 'int', tại sao tôi cần một cảnh báo khi so sánh một int int khác? – Mike

+0

Tôi nghĩ rằng nó chỉ cảnh báo bạn bởi vì nó có thể dễ dàng là một sai lầm. Điều duy nhất tôi có thể nghĩ đến là các enums có thể được đại diện bởi các loại khác nhau. – teppic

Trả lời

11

Đây không phải là cảnh báo vì vấn đề tuân thủ tiêu chuẩn, đó là một trong những cảnh báo "điều này dường như không đúng". Nếu bạn nghĩ về cách sử dụng điển hình của enums, việc so sánh như vậy không có ý nghĩa gì trong nhiều trường hợp. Ví dụ:

enum Day { 
    Sunday, 
    Monday, 
    Tuesday, 
    Wednesday, 
    Thursday, 
    Friday, 
    Saturday 
}; 

enum Month { 
    January, 
    February, 
    March, 
    April, 
    May, 
    June, 
    July, 
    August, 
    September, 
    October, 
    November, 
    December 
}; 

enum Day day = Wednesday; 
enum Month month = April; 

if (day == month) { ... } 

Điều này đánh giá đúng, nhưng nói chung, việc so sánh sẽ không có ý nghĩa nhiều. Nếu bạn biết bạn có nghĩa là nó, các typecast sẽ thuyết phục trình biên dịch, như bạn đã lưu ý.

+0

Vâng, nói chung là có ý nghĩa ... tất nhiên trong * my * thực tế việc sử dụng nó có ý nghĩa hơn nhiều so với hàng tháng, nhưng không có cách nào để 'gcc' biết điều đó. ;) Tôi không cho rằng bạn biết cách tắt '-Wenum-compare' khi' -Wall' đang bật? – Mike

+1

@Mike Try '-Wall -Wno-enum-compare' cùng nhau. Điều đó sẽ khiến bạn "cảnh báo" tất cả trừ đi cảnh báo so sánh enum. – FatalError

+3

Bah, người vẫn sử dụng chủ nhật là ngày đầu tiên trong tuần? (+1, BTW) –

2

Nó cảnh báo bạn bởi vì bạn phải cảnh báo gắn cờ. Mô tả cờ không giải thích lý do tại sao nó tồn tại, nhưng có thể giả định rằng nó tồn tại để ngăn chặn sự so sánh ngẫu nhiên giữa các kiểu liệt kê khác nhau, vì điều này thường là là một lỗi.

Hơn nữa, bạn chính xác rằng bạn có thể sử dụng các giá trị liệt kê giống như bạn có thể int hằng số. Và nếu bạn nói if (myf == c) thì rất có thể sẽ không đưa ra cảnh báo (tôi nói rất có thể vì tôi chưa thử nghiệm, và GCC thành thật có thể làm bất cứ điều gì nó muốn với cảnh báo đó, nhưng về mặt kỹ thuật, c chỉ là một hằng số không thể tách rời không mang theo loại enum second). Nhưng thay vào đó, bạn so sánh rõ ràng hai giá trị của các loại liệt kê khác nhau.

+1

'nếu bạn nói nếu (myf == c) sau đó nó rất có thể sẽ không ném một cảnh báo' - một theroy thú vị , Tôi đã thử nó và nó vẫn ném một (fyi). Ok, vì vậy vì tôi cần '-Wall -Werror' Tôi đang mắc kẹt khi thực hiện một kiểu định dạng mà ở đó cơ bản là không cần thiết. – Mike

+1

@Mike - chỉ biên dịch với '-Wno-enum-compare'? – teppic

+0

@Mike: Ok, vì vậy GCC đang xem xét rằng một tình huống cảnh báo-có thể anyway. Không đáng ngạc nhiên, vì cảnh báo này là tất cả về việc gắn cờ thứ gì đó không phải là bất hợp pháp về mặt kỹ thuật. –

1

Cảnh báo của nó nhưng như bạn đã biên dịch với -Wall -Werror tất cả cảnh báo được coi là lỗi Phần còn lại bạn có thể tìm thấy điều gì đó trong cùng một câu hỏi.

Is there a correct way to avoid warnings when comparing two different enums?

liên quan

Hims

+0

FYI, tôi đã thấy liên kết đó khi đăng câu hỏi, nhưng khi ngôn ngữ khác, câu hỏi về mặt kỹ thuật khác nhau và câu trả lời không có ý nghĩa ở đây; Tôi không quan tâm đến nó. Nên có đề cập đến nó trong câu hỏi tuy nhiên. – Mike

1

if((int)myf == (int)mys)

Điều đó sẽ làm điều đó. Nhưng đó là thực hành dơ bẩn, chỉ sử dụng nó nếu cả hai enums là khác nhau "phiên bản" của cùng một nhóm, giống như mới hơn sẽ chứa từ khóa mới ở cuối.

Các vấn đề liên quan