C ++ 20 disetujui! Apa yang diharapkan dan apa yang harus disiapkan untuk pengembang di C ++ 23

Suatu hari di Praha, pertemuan komite standardisasi internasional C ++ berlangsung. Dan-dan-dan-dan ...



C ++ 20 siap! Tetap memberi cap dari ISO, tetapi ini adalah langkah formal murni yang seharusnya tidak ada masalah.

Selamat untuk semuanya atas acara yang luar biasa ini! Konsep, Coroutine, Modul, Rentang, std :: format, algoritma constexpr new dan constexpr + vektor + string, datetime, jthread, span, bit_cast dan banyak inovasi kecil dan besar lainnya.

Apa yang berhasil mereka tambahkan dan perbaiki pada saat terakhir, apa yang mereka usulkan untuk dilanggar dan apa yang semua orang ingin lihat dalam C ++ 23 - tentang semua ini di bawah potongan.

Trik dari C ke C ++ 20


Baru-baru ini, ada tradisi menakut-nakuti pengembang pemula dengan perilaku tidak terdefinisi (UB) di C ++. Sudah waktunya untuk mengubahnya!

Di sini, misalnya, kode tersebut benar-benar valid untuk C:

struct X { int a, b; };

X *make_x() {
  X *p = (X*)malloc(sizeof(struct X));
  p->a = 1;
  p->b = 2;
  return p;
}

Tetapi dalam C ++ ada masalah besar dengan itu. C beroperasi dengan byte, dan C ++ bekerja dengan objek. Tetapi objek memiliki masa hidup, dan sebelum C ++ 20, awal kehidupan untuk objek dianggap dari panggilan baru.

Komite sangat memperhatikan pekerjaan tingkat rendah dengan byte dan struktur sederhana. Mereka mengadopsi perbaikan yang mengatakan bahwa serangkaian fungsi tertentu (memcpy, memmove, malloc, aligned_alloc, calloc, realloc, bit_cast) memulai masa hidup objek. Sekarang sebagian besar trik C tingkat rendah dijamin bekerja di C ++.

bool menjadi lebih andal dalam C ++ 20


Tebak kesalahannya:

template <typename T, size_t N>
auto count_unique(const std::array<T, N>& v) {
    return std::unordered_set<T>{v.begin(), v.end()}.size();
}

Menjawab
T bool v.begin() v.end() (, libc++ libstdc++) — count_unique 1.

- , std::unordered_set<bool>{v.begin(), v.end()} bool std::unordered_set<bool>{true, true}.

Transformasi dalam bool sekarang dianggap transformasi penyempitan. Ini memungkinkan kami menemukan masalah dalam banyak basis kode (lebih banyak contoh dalam kalimat P1957 itu sendiri ).

Konsep C ++ 20 dibuat lebih cepat


Sampai saat ini, Anda dapat menulis konsep seperti ini:

template <class T>
concept Reservable = requires(T v) {
    v.reserve(int{});
};

Dan terkejut bahwa itu mengembalikan hasil yang berbeda:

struct Test;

static_assert(!Reservable<Test>);

struct Test {
    void reserve(int);
};

static_assert(Reservable<Test>);

Terakhir kali, kami mengirim komentar dari negara: "Buat itu mustahil untuk menggunakan tipe konsep yang tidak lengkap, karena jika tidak Anda akan mendapatkan banyak pelanggaran ODR". Komentar kami ditolak, tetapi kami sebagian mendapatkan hasil yang diinginkan sekarang dengan proposal P2104.

Sebagai bonus, kami mendapatkan kompilasi yang lebih cepat, karena kompiler sekarang berhak untuk men-cache hasil penerapan konsep ke tipe.

Suntingan kecil dalam C ++ 20


  • Kisaran mendapat metode ukuran.
  • Linkage internal entitas tidak lagi terlihat ketika instantiating entitas linkage modul (kompiler akan memberi tahu Anda apa yang salah pada tahap kompilasi).
  • Kami memutar aturan untuk modul sehingga lebih mudah bagi alat apa pun untuk bekerja dengannya.

Dan mari kita hancurkan semuanya dalam C ++ 23 atau C ++ 26?


Perdebatan yang berkepanjangan telah memicu proposal untuk Aplikasi Binary Interface (ABI, jangan bingung dengan API). Pertanyaan menarik diajukan:

1. Kami dapat sepenuhnya mengubah ABI di C ++ 23 dan mendapatkan keuntungan kinerja 5-10%.


Selain itu, semua pustaka C ++ lama harus dibangun kembali, mereka tidak akan dapat menautkan ke pustaka dengan ABI baru. Anda tidak dapat menggunakan perpustakaan yang dibangun oleh versi C ++ sebelumnya dalam proyek C ++ 23.

Yah, tentu saja, akan selalu ada perangkat lunak komersial lama yang tidak akan dipasang kembali oleh siapa pun, tetapi itu akan menyeret perpustakaan standarnya (ya, video game, saya berbicara tentang Anda!).

Dengan sedikit margin suara, ABI memutuskan untuk tidak menembus C ++ 23.

2. Mari beri pengguna jaminan bahwa kami akan berusaha untuk tidak merusak / mengubah ABI.


Dan kemudian mereka memutuskan untuk tidak memberikan jaminan. Vendor yang berbeda memiliki rencana yang berbeda untuk platform mereka, dan kadang-kadang mereka mampu mematahkan ABI, seringkali tanpa membahayakan pengguna.

Dan mari kita tambahkan di mana saja kecuali?


Secara historis, fungsi dengan prasyarat dalam standar tidak ditandai sebagai kecuali, bahkan jika mereka tidak pernah melempar pengecualian. Di sini, misalnya, operator -> have std :: opsional:

constexpr const T* operator->() const;
constexpr T* operator->();
    Requires: *this contains a value.
    Returns: val.
    Throws: Nothing.

Dia tidak melempar apa pun, tetapi alih-alih noexcept itu mengatakan dalam kata-kata bahwa "Melempar: Tidak Ada", karena ada prasyarat "* ini mengandung nilai".

Pengguna tanpa kecuali akan lebih jelas. Ide bagus di P1656 !



Tidak!

Ada seluruh subkelompok SG21: Kontrak, yang muncul dengan mekanisme umum untuk memeriksa kontrak (pra dan pascakondisi). Penangan kontrak dapat melempar pengecualian, jika pengecualian dilemparkan dari fungsi noexcept, itu akan menjadi std :: terminate dan aplikasi akan crash. Jika Anda memasukkan kruk khusus yang pengecualian untuk kontrak dapat terbang keluar dari fungsi noexcept ... Pokoknya, semuanya rusak, ketik sifat dipandu oleh kehadiran noexcept, dan mereka mulai berbohong kepada Anda, fungsi yang ditandai dengan noexcept dengan prasyarat akan mengeluarkan pengecualian.

Tapi ini bukan masalah terbesar. Ada garpu perpustakaan standar, yang sekarang sudah dalam beberapa kasus secara eksplisit memasukkan pemeriksaan prasyarat. Misalnya, apakah Anda memiliki proyek kritis, ketersediaannya harus dimaksimalkan. Anda menggunakan garpu yang serupa, dan jika seseorang tiba-tiba memanggil std :: vector :: back () untuk vektor kosong, pengecualian melempar, yang diproses lebih tinggi dalam kode dan fallback mulai digunakan. Dengan pengeditan dari P1656, perpustakaan seperti itu tidak lagi dapat dianggap standar.

Dan ini tidak semua masalah! .. Tidak hanya akan ada tambahan kecuali untuk perpustakaan standar membawa efek positif dalam bentuk penurunan ukuran file biner atau lebih banyak kinerja, tidak hanya perubahan akan memecahkan kode setidaknya dua perusahaan, tidak hanya akan menghancurkan salah satu cara penggunaan kontrak ... begitu juga proposal itu disetujui dalam dua subkelompok.

Kelebihan RG21


Seperti biasa, kami bekerja di berbagai subkelompok, berbagi pengalaman implementasi, mempresentasikan proposal, yang penulisnya tidak dapat datang.

Salah satu ide luar biasa yang beruntung kami sajikan adalah ide Anton Zhilin P2025 Guaranteed elision untuk objek pengembalian bernama . Implementasinya akan memungkinkan pembuatan fungsi pabrik untuk objek tanpa menyalin dan memindahkan konstruktor. Sebenarnya, ini adalah langkah destruktif, yang telah diam-diam ada dalam standar sejak pertengahan 90-an dan secara khusus dilarang oleh aturan bahasa individu.

Kami berhasil menyeret ide melalui contoh EWG-I dan EWG berkat elaborasi ide yang sangat baik oleh penulis sendiri. Tahap CWG tetap, dan setelah beberapa pertemuan ada setiap kesempatan untuk melihat kata-kata yang diperlukan dalam standar, dan implementasi pertama dalam kompiler.

Selain ide ini, kami menyeret ide P1990R0: Tambahkan operator [] ke std :: initializer_list via LEWG-I, mendapat umpan balik yang berguna pada P1944R0: constexpr <cstring> dan <cwchar> . Kedua gagasan Daniil Goncharov memiliki setiap kesempatan untuk berada di C ++ 23.

Di bidang std :: hash, kegagalan tak terduga menunggu kami. Diskusi p1406r1: Tambahkan lebih banyak std :: hash spesialisasi tiba-tiba berubah menjadi diskusi tentang kasus batas merosot dan kemungkinan C ++ 2 * jauh. Akibatnya, panitia memutuskan untuk tidak mengubah apa pun.

Dengan SG6 dan Angka tidak tumbuh bersama. Diskusi utama SG6 berpotongan dengan diskusi ABI, itulah sebabnya kuorum dalam SG6 tidak menumpuk. Karena p1889 ini : C ++ Numerics Work In Progress , P2010: Hapus operator iostream dari P1889 danP1890: Masalah C ++ Numerics In Progress tidak dibahas.

C ++ 23 Paket


Sejak awal pengembangan C ++ 20, panitia mulai bertindak sesuai rencana. Yaitu, untuk mengidentifikasi beberapa ide utama yang menarik untuk standar berikutnya, setelah itu pada semua pertemuan berikutnya untuk tidak mempertimbangkan proposal pada topik lain, jika tidak semua telah dibahas pada yang utama.

Untuk C ++ 23, rencana seperti itu baru saja disetujui di Praha. Prioritas utama C ++ 23:

  1. Dukungan Corutin di perpustakaan standar
  2. Konversi pustaka standar ke modul
  3. Pelaksana
  4. Jaringan

Di paragraf pertama, semua orang akan dipandu oleh perpustakaan CppCoro . Jadi jika Anda sudah ingin menggunakan C ++ 20 coroutine, Anda harus mulai dengan menggunakan perpustakaan ini.

Dengan modul, poin kedua, Anda hanya perlu duduk dan melakukannya, tidak ada kesulitan khusus yang diharapkan.

Tapi Pelaksana adalah masalah. Desain mereka tidak jelas, tidak semua kasus pengguna dicakup, dalam bentuk mereka saat ini mereka tidak digunakan oleh siapa pun, dan desainnya masih belum disetujui.

Komite juga setuju untuk memprioritaskan proposal di bidang-bidang berikut:

  • Refleksi
  • Pencocokan pola
  • Kontrak

Alih-alih total


C ++ 20 sudah siap, saatnya bekerja pada C ++ 23! Rapat Komite berikutnya akan diadakan di musim panas, jadi jika Anda memiliki gagasan yang layak tentang standar baru - bagikan di stdcpp.ru dan ProCxx yang mengobrol dengan Telegram .

Nah, semua orang yang ingin mengobrol dengan perwakilan panitia langsung - lihat pertemuan dan konferensi C ++ *:


* Life hack: Anda tidak perlu membayar tiket konferensi jika Anda seorang pembicara.

All Articles