Apakah kompilator diizinkan untuk mengoptimalkan anggota data pribadi?

Dec 08 2020

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

31 PeterCordes Dec 08 2020 at 23:19

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 .hjika 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 .cppdan .hfile 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.

17 KonradRudolph Dec 08 2020 at 22:26

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).

11 PasserBy Dec 08 2020 at 22:30

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 Apertama kali digunakan, dan bahwa ia tidak akan pernah tahu apakah beberapa kode di masa mendatang dapat mengakses x, ia harus memperbaiki memori Auntuk menampungnya x.