Bagikan melalui


Compiler Warning (level 4) C4471

'enumerasi': deklarasi penerusan enumerasi yang tidak terlingkup harus memiliki jenis yang mendasar (diasumsikan int)

Deklarasi penerusan enumerasi yang tidak terlingkup ditemukan tanpa penentu untuk jenis yang mendasar. Secara default, Visual C++ mengasumsikan adalah jenis yang mendasar int untuk enumerasi. Ini dapat menyebabkan masalah jika jenis yang berbeda digunakan dalam definisi enumerasi, misalnya, jika jenis eksplisit yang berbeda ditentukan, atau jika jenis yang berbeda secara implisit diatur oleh penginisialisasi. Anda mungkin juga memiliki masalah portabilitas; kompilator lain tidak mengasumsikan int adalah jenis enumerasi yang mendasar.

Peringatan ini nonaktif secara default; Anda dapat menggunakan /Wall atau /wN4471 untuk mengaktifkannya pada baris perintah, atau menggunakan peringatan #pragma dalam file sumber Anda.

Contoh

Dalam beberapa kasus, peringatan ini memacu. Jika deklarasi penerusan untuk enumerasi muncul setelah definisi, peringatan ini dapat diaktifkan. Misalnya, kode ini valid, meskipun dapat menyebabkan C4471:

// C4471a.cpp
// Compile with: cl /c /w14471 C4471a.cpp
enum Example { item = 0x80000000UL };
enum Example;    // Spurious C4471
// ...

Secara umum, aman untuk menggunakan definisi lengkap untuk enumerasi yang tidak tercakup alih-alih deklarasi maju. Anda dapat menempatkan definisi dalam file header dan menyertakannya dalam file sumber yang merujuk ke file tersebut. Ini berfungsi dalam kode yang ditulis untuk C++98 dan yang lebih baru. Kami merekomendasikan solusi ini untuk portabilitas dan kemudahan pemeliharaan.

// C4471b.cpp
// Compile with: cl /c /w14471 C4471b.cpp
enum Example;    // C4471
// To fix, replace the line above with the enumeration definition:
// enum Example { item = 0x80000000UL };
// ...

Di C++11, Anda dapat menambahkan jenis eksplisit ke enumerasi yang tidak terlingkup dan ke deklarasi penerusannya. Kami merekomendasikan solusi ini hanya jika logika penyertaan header kompleks mencegah penggunaan definisi alih-alih deklarasi maju. Solusi ini dapat menyebabkan masalah pemeliharaan: jika Anda mengubah jenis dasar yang digunakan untuk definisi enumerasi, Anda juga harus mengubah semua deklarasi ke depan agar cocok, atau Anda mungkin memiliki kesalahan senyap dalam kode Anda. Anda dapat meneruskan deklarasi ke dalam file header untuk meminimalkan masalah ini.

File sumber C4471c.cpp:

// C4471c.cpp
// Client code for enumeration defined in C4471d.cpp
// Compile with: cl /c /w14471 C4471c.cpp C4471d.cpp
enum Example;    // C4471, int assumed
// To fix, replace the lines above with the forward declarations:
// enum Example : unsigned;
// ...

File sumber C4471d.cpp:

// C4471d.cpp
// Definition for enumeration used in C4471c.cpp
// Compile with: cl /c /w14471 C4471c.cpp C4471d.cpp
enum Example : unsigned { item = 0x80000000 }; // explicit type
// ...

Jika Anda menentukan jenis eksplisit untuk enumerasi, kami sarankan Anda juga mengaktifkan peringatan C4369, yang aktif secara default. Ini mengidentifikasi kasus di mana item enumerasi memerlukan jenis yang berbeda dari jenis yang ditentukan secara eksplisit.

Anda dapat mengubah kode untuk menggunakan enum terlingkup, fitur yang baru di C++11. Definisi dan kode klien apa pun yang menggunakan jenis enumerasi harus diubah untuk menggunakan enum terlingkup. Kami sarankan Anda menggunakan enum cakupan jika Anda memiliki masalah dengan polusi namespace, karena nama item enumerasi yang ditentukan terbatas pada cakupan enum. Fitur lain dari enum tercakup adalah bahwa anggotanya tidak dapat dikonversi secara implisit ke jenis integral atau enumerasi lain, yang dapat menjadi sumber bug halus.

File sumber C4471e.cpp:

// C4471e.cpp
// Client code for scoped enumeration defined in C4471f.cpp
// Compile with: cl /c /w14471 C4471e.cpp C4471f.cpp
enum Example;    // C4471
// To fix, replace the line above with the forward declaration:
// enum class Example;
// ...

File sumber C4471f.cpp:

// C4471f.cpp
// Definition for scoped enumeration used in C4471e.cpp
// Compile with: cl /c /w14471 C4471e.cpp C4471f.cpp
enum class Example { item = 0 };
// ...