Apakah nilai enum default di C sama untuk semua kompiler?

107

Ketika mendeklarasikan sebuah enum seperti yang ditunjukkan di bawah ini, jangan semua kompiler C menetapkan nilai default sebagai x=0, y=1dan z=2pada kedua sistem Linux dan Windows?

typedef enum {
    x,
    y,
    z
} someName;
SSS
sumber
3
Ya, itu diwajibkan oleh standar, dan saya yakin seseorang akan dapat mengutipnya.
Nemo

Jawaban:

115

Iya. Kecuali ditentukan lain dalam definisi pencacahan, pencacah awal selalu bernilai nol dan nilai pencacah berikutnya satu lebih besar dari pencacah sebelumnya.

James McNellis
sumber
14
dan, perilaku identik ini dibutuhkan oleh C dan C ++. Dalam C ++, ini adalah [dcl.enum]: "Jika pencacah pertama tidak memiliki penginisialisasi, nilai konstanta yang bersangkutan adalah nol. Definisi pencacah tanpa penginisialisasi memberi pencacah nilai yang diperoleh dengan meningkatkan nilai pencacah sebelumnya sebesar satu."
Ben Voigt
3
Ya, dan juga bahasa lain yang diawali dengan huruf C, seperti C #.
James McNellis
70

Standar C99

The N1265 C99 rancangan mengatakan di 6.7.2.2/3 "Pencacahan specifier"

Pencacah dengan = mendefinisikan konstanta pencacahannya sebagai nilai dari ekspresi konstanta. Jika pencacah pertama tidak memiliki =, maka nilai konstanta pencacahannya adalah 0. Setiap pencacah berikutnya dengan no = mendefinisikan konstanta pencacahannya sebagai nilai konstanta yang diperoleh dengan menambahkan 1 pada nilai konstanta pencacahan sebelumnya. (Penggunaan pencacah dengan = dapat menghasilkan konstanta pencacahan dengan nilai yang menduplikasi nilai lain dalam pencacahan yang sama.)

Jadi yang berikut ini selalu berpegang pada implementasi yang sesuai:

main.c

#include <assert.h>
#include <limits.h>

enum E {
    E0,
    E1,
    E2 = 3,
    E3 = 3,
    E4,
    E5 = INT_MAX,
#if 0
    /* error: overflow in enumeration values */
    E6,
#endif
};

int main(void) {
    /* If unspecified, the first is 0. */
    assert(E0 == 0);
    assert(E1 == 1);
    /* Repeated number, no problem. */
    assert(E2 == 3);
    assert(E3 == 3);
    /* Continue from the last one. */
    assert(E4 == 4);
    assert(E5 == INT_MAX);
    return 0;
}

Kompilasi dan jalankan:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

Diuji di Ubuntu 16.04, GCC 6.4.0.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
7

Jika nilai pertama dari variabel enum tidak diinisialisasi maka compiler C secara otomatis memberikan nilai 0. Kompilator terus meningkatkan nilai variabel enum sebelumnya sebesar 1.

Misalnya:

enum months{jan,feb,mar}

Penjelasan: Nilai jan akan menjadi 0, feb akan menjadi 1, mar akan menjadi 2.

enum months{jan=123,feb=999,mar}

Penjelasan: Nilai jan jadi 123, feb 999, mar jadi 1000.

enum months{jan='a',feb='s',mar}

Penjelasan: Nilai jan akan menjadi 'a', feb akan menjadi 's', mar akan menjadi 't'.

Vignesh vicky
sumber
1
keberadaan mar 't'tidak dijamin, mungkin ada himpunan karakter yang hurufnya tidak dalam urutan abjad yang berurutan
MM
-15

Ya, enum value bydefult mulai dari 0 hingga elemen n ke platform apa pun.

Devidas Gaikwad
sumber
14
Pertimbangkan bagaimana jawaban Anda menambah kumpulan jawaban. Artinya, bagaimana jawaban baru Anda (5 tahun kemudian) menambahkan sesuatu yang baru yang tidak tercakup dalam jawaban lain? Sekilas, sepertinya kurang informatif dibandingkan dua jawaban lainnya.
LawfulEvil
2
Ehhh @LawfulEvil santai. Banyak jawaban memberi orang melihat ini di masa depan berbagai perspektif. Meskipun demikian, ini adalah jawaban dengan format yang buruk dan tidak informatif, tetapi jawaban yang cukup banyak tidak buruk.
Kenny Worden