Mengapa sizeof disebut operator waktu kompilasi?

12

Awalnya, ini adalah bagian dari pertanyaan lain .

Mengapa sizeofdisebut operator waktu kompilasi? Bukankah itu sebenarnya operator run-time? Dan jika itu memang operator waktu kompilasi, bagaimana hal itu membantu dalam menghasilkan kode portabel yang berjalan sama di komputer yang berbeda? Tolong jelaskan secara rinci.

The Peaceful Coder
sumber
4
dijawab secara detail di SO: Mengapa sizeof (x ++) tidak bertambah x?
Agak
3
Bagaimana Anda mengharapkan ukuran suatu tipe berubah saat runtime?
@MichaelT: Ukuran instance dari suatu jenis pasti dapat berubah - ada polimorfisme kelas, setelah semua. Saya berpendapat bahwa sizeof(polymorphic_ptr*)menjadi konstan sangat berlawanan dengan intuisi dan konyol. Ya, itu cara C ++, tapi tetap saja konyol.
Pasang kembali Monica
@KubaOber Memang. Saya hanya ingin tahu bagaimana OP berpikir harus berperilaku dalam kasus yang berbeda dan mudah-mudahan mendapatkan beberapa kode yang akan menunjukkan kebingungannya atas hal ini untuk membantu memperluas pertanyaan.
4
Datang untuk membatalkan jawaban "karena beroperasi pada waktu kompilasi", dibiarkan kecewa.
Ben Jackson

Jawaban:

23

sizeof()memberi Anda ukuran tipe data , bukan ukuran instance tertentu dari tipe dalam memori.

Misalnya, jika Anda memiliki objek data string yang mengalokasikan array karakter ukuran variabel saat runtime, sizeof()tidak dapat digunakan untuk menentukan ukuran array karakter itu. Itu hanya akan memberi Anda ukuran pointer.

Ukuran tipe data selalu diketahui pada waktu kompilasi.


sumber
3
Karena C (++) tidak memiliki metadata objek run-time, Anda juga tidak bisa mendapatkan hal-hal itu pada saat run time.
C. Ross
5
Sebenarnya, jika Anda menggunakan sizeofarray, Anda akan mendapatkan ukuran array (yaitu ukuran elemen dikalikan jumlah elemen). Tetapi jika Anda menggunakannya pada pointer, Anda hanya mendapatkan ukuran pointer. Jadi, karena dalam kebanyakan kasus di mana Anda ingin mengetahui ukuran sebuah array, Anda hanya memiliki sebuah pointer, itu tidak terlalu berguna.
sepp2k
1
@ Jens Pertanyaannya ditandai [C ++] dan VLA tidak membuatnya menjadi standar C ++.
authchir
13

karena seluruh ukuran "panggilan" dihitung pada waktu kompilasi dan apa pun yang ada di antara kurung dibuang dan tidak dijalankan saat runtime,

hasilnya murni berdasarkan info tipe statis yang tersedia untuk kompiler

orang aneh
sumber
7

Mengapa sizeof disebut operator waktu kompilasi?

Karena, pada waktu kompilasi, kompiler menghitung ukuran ekspresi dan pengganti yang mengkompilasi nilai konstanta waktu.

Bukankah itu sebenarnya operator run-time?

Tidak. Anda bahkan dapat menggunakan sizeofuntuk mengevaluasi ukuran ekspresi yang tidak dapat Anda jalankan secara hukum (yaitu, yang akan menimbulkan Perilaku Tidak Terdefinisi), selama kompilator dapat mengetahui apa jenis ekspresi itu.

Juga, bahkan sebelum C ++ 11 constexpr, Anda bisa menggunakan sizeofekspresi dengan cara yang tidak bisa Anda gunakan dengan ekspresi run-time.

Dan jika itu memang operator waktu kompilasi, bagaimana hal itu membantu dalam memproduksi kode portabel ...

Jenis dapat bervariasi dalam ukuran pada platform yang berbeda. Menggunakan sizeofekspresi alih-alih asumsi hard-coded berarti kode Anda tidak akan rusak ketika Anda mengkompilasi pada platform yang berbeda dan tipe Anda berubah ukuran.

Tak berguna
sumber
1
Yah, saya menemukan ini jawaban yang paling berguna;). Bro (dengan asumsi Anda laki-laki), saya ragu. Apakah Anda bermaksud mengatakan bahwa ketika orang mengatakan bahwa sizeof membuat program portable, mereka berarti bahwa kode sumber dapat dikompilasi tanpa kesalahan di semua mesin dan mereka tidak berarti bahwa program yang dapat dieksekusi dapat dijalankan di mesin apa pun. Baik ? Jika ini benar, keraguan saya menjadi sangat jelas.
The Peaceful Coder
1
Ya, kodenya portabel, dalam arti Anda dapat mengompilasi (berbeda) biner yang benar untuk setiap platform.
berguna
5

C ++ sebenarnya tidak menyimpan metadata untuk objek saat runtime sehingga pemeriksaan ukuran harus waktu kompilasi. Untuk contoh bagaimana C ++ tidak memvalidasi ukuran, deklarasikan array intdari beberapa ukuran arbitrer dan baca setelah itu. Jika Anda beruntung, Anda akan mendapatkan segfaulttetapi lebih mungkin Anda hanya membaca omong kosong, karena C ++ tidak melacak ukuran array Anda.

Lihat Bisakah program C / C ++ membuat kesalahan dari pembacaan melewati akhir array (UNIX)? untuk contoh dari SO.

C. Ross
sumber