Saya tahu bahwa setidaknya salah satu perubahan dalam C ++ 11 yang akan menyebabkan beberapa kode lama berhenti dikompilasi: pengenalan explicit operator bool()
di perpustakaan standar, menggantikan contoh lama dari operator void*()
. Memang, kode yang akan dipecah ini mungkin kode yang seharusnya tidak valid di tempat pertama, tetapi tetap saja merupakan perubahan besar: program yang dulu valid tidak lagi.
Apakah ada perubahan melanggar lainnya?
export
kata kunci? Saya akan memberi saya mantel.mystream.good()
tidak sama denganbool(mystream)
?good()
benar jika tidak ada bendera yang ditetapkan.bool(mystream)
masih salah jika hanyaeofbit
disetel.!mystream.fail()
akan menjadi setara yang benar.Jawaban:
FDIS memiliki bagian untuk ketidakcocokan, pada lampiran
C.2
"C ++ dan ISO C ++ 2003".Ringkasan, memparafrasekan FDIS di sini, untuk membuatnya (lebih baik) cocok sebagai jawaban SO. Saya menambahkan beberapa contoh saya sendiri untuk menggambarkan perbedaan.
Ada beberapa ketidakcocokan yang berhubungan dengan perpustakaan di mana saya tidak tahu persis implikasinya, jadi saya meninggalkannya untuk diuraikan oleh orang lain.
Bahasa inti
(diakui bukan masalah kompatibilitas bagi kebanyakan orang).
Contoh oleh saya:
Trik sizeof seperti itu telah digunakan oleh beberapa SFINAE, dan perlu diubah sekarang :)
Contoh oleh saya:
Kode ini memanggil
terminate
C ++ 0x, tetapi tidak di C ++ 03. Karena spesifikasi pengecualian implisitA::~A
dalam C ++ 0x adalahnoexcept(true)
.Dalam C ++ 03,
>>
akan selalu menjadi token operator-shift.Contoh oleh saya:
Di C ++ 03, ini panggilan
f(long)
, tetapi di C ++ 0x, ini panggilanf(int)
. Perlu dicatat bahwa di C ++ 03 dan C ++ 0x, panggilan berikutf(B)
(konteks instantiasi masih hanya mempertimbangkan deklarasi linkage eksternal).Pencocokan yang lebih baik
f(A)
tidak diambil, karena tidak memiliki tautan eksternal.Perubahan perpustakaan
sumber
export
, maka saya pikir TU lain tidak perlu bergantung pada instantiasi eksplisit, tetapi bisa instantiate template itu sendiri. Maka akan membuat perbedaan apakah fungsi tautan internal terlihat dalam konteks instantiation.Arti kata kunci otomatis berubah.
sumber
auto
kata kunci, ada yang salah dengan kode Anda. Kenapa Anda akan menggunakannya?auto
valid tetap valid di C ++ 11.int main() { auto int i = 0; return i; }
benar-benar valid C ++ 03, tetapi kesalahan sintaksis dalam C ++ 11 Satu-satunya peringatan yang bisa saya dapatkan dari kompiler adalah dalam mode C ++ 03 adalah peringatan tentang kompatibilitas.Melanggar perubahan?
Nah, untuk satu hal, jika Anda menggunakan
decltype
,constexpr
,nullptr
, dll sebagai pengidentifikasi maka Anda mungkin berada dalam kesulitan ...sumber
Beberapa ketidakcocokan inti yang tidak tercakup oleh bagian ketidakcocokan:
C ++ 0x memperlakukan nama kelas yang disuntikkan sebagai templat, jika nama dilewatkan sebagai argumen ke parameter templat templat, dan sebagai jenis jika dilewatkan ke parameter jenis templat.
Kode C ++ 03 yang valid dapat berperilaku berbeda jika bergantung pada nama kelas yang disuntikkan untuk selalu menjadi tipe dalam skenario ini. Contoh kode diambil dari PR dentang saya
Dalam C ++ 03, kode memanggil yang kedua
g
kali.C ++ 0x membuat beberapa nama yang bergantung pada C ++ 03 menjadi sekarang tidak tergantung. Dan memerlukan pencarian nama untuk nama-nama terkualifikasi yang tidak bergantung yang merujuk kepada anggota templat kelas saat ini untuk diulangi saat instantiasi, dan memerlukan verifikasi bahwa nama-nama ini mencari dengan cara yang sama seperti yang dilakukan pada konteks definisi templat.
Kode C ++ 03 yang valid yang bergantung pada aturan dominasi sekarang tidak dapat dikompilasi lagi karena perubahan ini.
Contoh:
Kode C ++ 03 ini valid yang memanggil
A<int>::f
tidak valid dalam C ++ 0x, karena pencarian nama ketika instantiating akan menemukanA<int>::f
bertentanganB::f
, menyebabkan konflik dengan pencarian definisi-at.Pada titik ini, tidak jelas apakah itu cacat dalam FDIS. Panitia mengetahui hal ini dan akan mengevaluasi situasinya.
Deklarasi menggunakan di mana bagian terakhir sama dengan pengidentifikasi di bagian terakhir kualifikasi di nama yang memenuhi syarat yang menunjukkan kelas dasar, yang menggunakan deklarasi sekarang nama konstruktor, bukan anggota dengan nama itu.
Contoh:
Kode contoh di atas terbentuk dengan baik di C ++ 03, tetapi tidak terbentuk dengan baik di C ++ 0x, karena
A::B
masih tidak dapat diakses dimain
.sumber
Kegagalan ekstraksi aliran diperlakukan secara berbeda.
Contoh
Ubah proposal
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23
Referensi standar
Implementasi
GCC 4.8 mengeluarkan dengan benar untuk C ++ 11 :
GCC 4.5-4.8 semua output untuk C ++ 03 berikut ini, yang akan muncul sebagai bug:
Visual C ++ 2008 Express menampilkan dengan benar untuk C ++ 03:
Visual C ++ 2012 Express salah output untuk C ++ 11, yang akan muncul menjadi masalah status implementasi:
sumber
Bagaimana pengenalan operator konversi eksplisit merupakan perubahan besar? Versi lama akan tetap "valid" seperti sebelumnya.Ya, perubahan dari
operator void*() const
keexplicit operator bool() const
akan menjadi perubahan melanggar, tetapi hanya jika digunakan dengan cara yang salah dan keluar dari dirinya sendiri. Kode yang sesuai tidak akan rusak.Sekarang, perubahan lain yang melanggar adalah pelarangan penyempitan konversi selama inisialisasi agregat :
Sunting : Hanya pengingat,
std::identity<T>
akan dihapus dalam C ++ 0x (lihat catatan). Ini adalah struct kenyamanan untuk membuat tipe tergantung. Karena struct benar-benar tidak berbuat banyak, ini harus memperbaikinya:sumber
operator void*
.bool ok = cin >> a; cout << "done reading" << endl; if (ok) { ... }
Tidak ada yang benar-benar salah dengan itu di C ++ 03, namun itu telah menjadi kesalahan di C ++ 11. (Catatan: GCC 4.9 masih ada dioperator void*() const
sini, itulah sebabnya mengapa ia menerima kode dalam mode C ++ 11.)std::identity<T>
tidak dihapus di C ++ 11, karena itu bukan bagian dari C ++ 03. Itu memang ada sebentar di draft untuk C ++ 11, dan telah dihapus dari draft sebelum standarisasi.Ada banyak perubahan pada pustaka kontainer yang memungkinkan kode lebih efisien tetapi diam-diam memecah kompatibilitas ke belakang untuk beberapa kasus sudut.
Pertimbangkan, misalnya,
std::vector
konstruksi default, C ++ 0x, dan memecah perubahan .sumber
Sudah ada banyak diskusi tentang langkah implisit yang melanggar kompatibilitas
( halaman yang lebih tua dengan diskusi yang relevan )
Jika Anda membaca komentar, pemindahan implisit juga merupakan perubahan besar.
sumber
C ++ 03: valid.
C ++ 0x:
error: parameter declared 'auto'
sumber
struct x
dan tanpa nama.Fitur Bahasa
>>
Komponen Perpustakaan Standar
Fitur usang
sumber