bagaimana array [100] = {0} mengatur seluruh array menjadi 0?

140

Bagaimana kompiler mengisi nilai char array[100] = {0};? Apa keajaiban di baliknya?

Saya ingin tahu bagaimana internal compiler diinisialisasi.

Namratha Patil
sumber
1
Di C atau C ++? Mereka adalah dua pertanyaan terpisah.
Toby Speight

Jawaban:

163

Itu bukan sihir.

Perilaku kode ini dalam C dijelaskan pada bagian 6.7.8.21 dari spesifikasi C ( draf online spesifikasi C ): untuk elemen yang tidak memiliki nilai yang ditentukan, kompilator menginisialisasi pointer ke NULL dan tipe aritmatika menjadi nol ( dan secara rekursif menerapkan ini pada agregat).

Perilaku kode ini dalam C ++ dijelaskan pada bagian 8.5.1.7 dari spesifikasi C ++ ( draf online dari C ++ spec ): agregat kompilator-menginisialisasi elemen yang tidak memiliki nilai yang ditentukan.

Juga, perhatikan bahwa dalam C ++ (tetapi bukan C), Anda dapat menggunakan daftar penginisialisasi kosong, yang menyebabkan kompilator mengumpulkan-menginisialisasi semua elemen array:

char array[100] = {};

Adapun jenis kode apa yang mungkin dihasilkan oleh kompiler ketika Anda melakukan ini, lihat pertanyaan ini: Strange assembly from array 0-initialization

bk1e
sumber
Apakah semua kompiler C melakukan ini? Saya dituntun untuk percaya hanya Visual Studio yang melakukan ini.
JFA
1
draf online spesifikasi c ++ rusak, ada yang punya tautan baru?
Behrooz Karjoo
35

Implementasi tergantung pada pengembang kompiler.

Jika pertanyaan Anda adalah "apa yang akan terjadi dengan deklarasi seperti itu" - kompiler akan menetapkan elemen array pertama ke nilai yang Anda berikan (0) dan semua yang lain akan ditetapkan ke nol karena itu adalah nilai default untuk elemen array yang dihilangkan.

qrdl
sumber
Saya tidak memiliki sumber, tapi saya cukup yakin bahwa saya membaca di suatu tempat bahwa tidak ada nilai default untuk deklarasi array; Anda mendapatkan sampah apa pun yang sudah ada di sana. Tidak ada gunanya membuang-buang waktu untuk menetapkan nilai-nilai ini ketika Anda cenderung menimpa mereka.
Ryan Fox
10
Ryan, jika Anda tidak menetapkan nilai untuk elemen pertama bahwa seluruh array tidak diinisialisasi dan memang mengandung sampah, tetapi jika Anda menetapkan nilai untuk setidaknya satu elemen dari itu seluruh array menjadi diinisialisasi sehingga elemen yang tidak ditentukan dapat diinisialisasi secara implisit untuk 0.
qrdl
1
Untuk C ++ daftar penginisialisasi kosong untuk array terbatas default-menginisialisasi semua elemen.
dalle
2
@NatanYellin Di mana saya mengatakan bahwa ini tidak terdefinisi? Harap baca jawaban lengkap sebelum berkomentar dan downvoting.
qrdl
1
@ qrdl Anda benar. Saya salah mengerti komentar Anda tentang implementasinya. Sayangnya, saya tidak dapat mengubah suara saya sekarang.
Natan Yellin
27

Jika kompiler Anda adalah GCC, Anda juga dapat menggunakan sintaks berikut:

int array[256] = {[0 ... 255] = 0};

Silakan lihat http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits , dan perhatikan bahwa ini adalah fitur khusus kompiler .

lakshmanaraj
sumber
Selamat datang! karena Anda meminta Mencari macam lebih seperti trik, saya telah disediakan
lakshmanaraj
1
Anda tentu dapat melakukan ini jika Anda mau, tetapi ada kerugian yang jelas untuk mengandalkan ekstensi khusus kompiler seperti ini.
Dan Olson
@Dan Olson pertanyaannya sendiri adalah tentang kompiler dan karenanya memposting ini. Jika Anda merasa itu tidak berguna, saya akan menghapus.
lakshmanaraj
5
Ini tidak sia-sia, ini menarik. Peringatan hanya layak untuk dicatat.
Dan Olson
2
Itu hal-hal seperti ini membuat saya datang kembali ke SO dan membaca lebih dari beberapa jawaban atas ...
timday
19

Itu tergantung di mana Anda meletakkan inisialisasi ini.

Jika array statis seperti pada

char array[100] = {0};

int main(void)
{
...
}

maka itu adalah kompiler yang menyimpan 100 0 byte dalam segmen data program. Dalam hal ini Anda bisa menghilangkan penginisialisasi.

Jika array Anda otomatis, maka itu adalah cerita lain.

int foo(void)
{
char array[100] = {0};
...
}

Dalam hal ini pada setiap panggilan fungsi foo Anda akan memiliki memset tersembunyi.

Kode di atas setara dengan

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

dan jika Anda menghilangkan initializer array Anda akan berisi data acak (data stack).

Jika array lokal Anda dinyatakan statis seperti di

int foo(void)
{ 
static char array[100] = {0};
...
}

maka secara teknis kasus yang sama dengan yang pertama.

Piringan hitam
sumber