Apakah kompilator diizinkan untuk mengoptimalkan anggota data pribadi?
Jika kompilator dapat membuktikan bahwa anggota (pribadi) kelas tidak pernah digunakan, termasuk oleh calon teman, apakah standar mengizinkan kompilator untuk menghapus anggota ini dari footprint memori kelas?
Terbukti dengan sendirinya bahwa ini tidak mungkin untuk anggota yang dilindungi atau publik pada waktu kompilasi, tetapi mungkin ada keadaan di mana dimungkinkan mengenai anggota data pribadi untuk membuat bukti seperti itu.
Pertanyaan-pertanyaan Terkait:
- Di balik layar publik, pribadi dan dilindungi (memicu pertanyaan ini)
- Apakah compiler C ++ diizinkan untuk mengoptimalkan objek lokal yang tidak direferensikan (tentang objek otomatis)
- Akankah variabel statis selalu menggunakan memori? (tentang objek statis)
Jawaban
Mungkin dalam teori (bersama dengan anggota publik yang tidak terpakai), tetapi tidak dengan jenis ekosistem kompilator yang biasa kita gunakan (menargetkan ABI tetap yang dapat menautkan kode yang dikompilasi secara terpisah). Menghapus anggota yang tidak digunakan hanya dapat dilakukan dengan pengoptimalan seluruh program yang melarang pustaka terpisah 1 .
Unit kompilasi lain mungkin perlu disepakati sizeof(foo)
, tetapi itu bukan sesuatu yang dapat Anda peroleh dari a .h
jika bergantung pada verifikasi bahwa tidak ada implementasi perilaku fungsi anggota yang bergantung pada anggota privat.
Ingat C ++ hanya benar-benar menentukan satu program, bukan cara untuk melakukan perpustakaan. Bahasa yang ditentukan ISO C ++ kompatibel dengan gaya implementasi yang biasa kita gunakan (tentu saja), tetapi implementasi yang mengambil semua .cpp
dan .h
file sekaligus dan menghasilkan satu executable non-extensible mandiri dimungkinkan.
Jika Anda cukup membatasi penerapan (tidak ada ABI tetap), aplikasi seluruh program yang agresif dari aturan seolah-olah menjadi mungkin.
Catatan kaki 1: Saya akan menambahkan " atau mengekspor informasi ukuran ke kode lain yang sedang dikompilasi " sebagai cara untuk mengizinkan perpustakaan, jika kompilator sudah bisa melihat definisi untuk setiap fungsi anggota yang dideklarasikan di kelas. Tetapi jawaban @ PasserBy menunjukkan bahwa pustaka yang dikompilasi secara terpisah dapat menjadi hal yang menggunakan anggota pribadi yang dideklarasikan dengan cara yang pada akhirnya menghasilkan efek samping yang terlihat secara eksternal (seperti I / O). Jadi kita harus sepenuhnya mengesampingkan mereka.
Mengingat, anggota publik dan pribadi setara untuk tujuan pengoptimalan semacam itu.
Jika kompilator dapat membuktikan bahwa anggota (pribadi) kelas tidak pernah digunakan
Kompilator tidak dapat membuktikannya, karena anggota pribadi dapat digunakan di unit kompilasi lain. Secara konkret, ini dimungkinkan dalam konteks pointer ke anggota dalam argumen template menurut [temp.spec] / 6 dari standar, seperti yang awalnya dijelaskan oleh Johannes Schaub .
Jadi, ringkasannya: tidak, compiler tidak boleh mengoptimalkan anggota data pribadi lebih dari anggota publik atau dilindungi (tunduk pada aturan seolah-olah).
Tidak, karena Anda dapat menumbangkan sistem kontrol akses secara legal .
class A
{
int x;
};
auto f();
template<auto x>
struct cheat
{
friend auto f() { return x; }
};
template struct cheat<&A::x>; // see [temp.spec]/6
int& foo(A& a)
{
return a.*f(); // returns a.x
}
Mengingat bahwa kompilator harus memperbaiki ABI saat A
pertama kali digunakan, dan bahwa ia tidak akan pernah tahu apakah beberapa kode di masa mendatang dapat mengakses x
, ia harus memperbaiki memori A
untuk menampungnya x
.