Dimungkinkan untuk menulis sebuah fungsi, yang, ketika dikompilasi dengan kompilator C akan mengembalikan 0, dan ketika dikompilasi dengan kompilator C ++, akan mengembalikan 1 (sulusi sepele dengan
#ifdef __cplusplus
tidak menarik).
Sebagai contoh:
int isCPP()
{
return sizeof(char) == sizeof 'c';
}
Tentu saja, hal di atas hanya akan berfungsi jika sizeof (char)
tidak sama dengansizeof (int)
Solusi lain yang lebih portabel adalah seperti ini:
int isCPP()
{
typedef int T;
{
struct T
{
int a[2];
};
return sizeof(T) == sizeof(struct T);
}
}
Saya tidak yakin apakah contohnya 100% benar, tetapi Anda mengerti. Saya yakin ada cara lain untuk menulis fungsi yang sama juga.
Perbedaan apa, jika ada, antara C ++ 03 dan C ++ 11 yang dapat dideteksi saat run-time? Dengan kata lain, apakah mungkin untuk menulis fungsi serupa yang akan mengembalikan nilai boolean yang menunjukkan apakah itu dikompilasi oleh kompilator C ++ 03 yang sesuai atau kompiler C ++ 11?
bool isCpp11()
{
//???
}
sumber
Jawaban:
Bahasa Inti
Mengakses enumerator menggunakan
::
:Anda juga dapat menyalahgunakan kata kunci baru
Juga, fakta bahwa string literal tidak lagi diubah menjadi
char*
Saya tidak tahu seberapa besar kemungkinan Anda memiliki ini bekerja pada implementasi nyata. Salah satu yang mengeksploitasi
auto
Berikut ini didasarkan pada fakta bahwa
operator int&&
ada fungsi konversi keint&&
dalam C ++ 0x, dan konversi keint
diikuti oleh logika-dan di C ++ 03Kasus uji tersebut tidak berfungsi untuk C ++ 0x di GCC (terlihat seperti bug) dan tidak berfungsi dalam mode C ++ 03 untuk clang. Sebuah dentang PR telah diajukan .
The pengobatan modifikasi dari nama kelas disuntikkan template di C ++ 11:
Sepasang "deteksi apakah ini C ++ 03 atau C ++ 0x" dapat digunakan untuk mendemonstrasikan perubahan yang melanggar. Berikut ini adalah kasus pengujian yang diubah, yang awalnya digunakan untuk mendemonstrasikan perubahan tersebut, tetapi sekarang digunakan untuk menguji C ++ 0x atau C ++ 03.
Perpustakaan Standar
Mendeteksi kekurangan
operator void*
dalam C ++ 0x 'std::basic_ios
sumber
true
untuk MSVC 2005 dan seterusnya, dan kesalahan kompilasi di MSVC 2003.(...)
vs.(char*)
Saya sangat suka itu!Saya mendapat inspirasi dari Perubahan apa saja yang diperkenalkan di C ++ 11? :
Ini didasarkan pada string literal baru yang lebih diutamakan daripada perluasan makro.
sumber
#undef u8
maka penggunaan preprocessor hanya dapat diamati jika program Anda memiliki makro yang ditentukan sebelumnya bernamau8
(boooo). Jika itu adalah masalah nyata, itu masih dapat diatasi dengan menggunakan pragma / panggilan makro push / pop khusus implementasi (saya yakin sebagian besar implementasi memiliki ini).Bagaimana dengan cek menggunakan aturan baru untuk
>>
menutup template:Atau pemeriksaan cepat untuk
std::move
:sumber
std::move
?Tidak seperti C ++ sebelumnya, C ++ 0x memungkinkan jenis referensi dibuat dari jenis referensi jika jenis referensi dasar tersebut dimasukkan melalui, misalnya, parameter template:
Sayangnya, penerusan sempurna datang dengan harga merusak kompatibilitas ke belakang.
Pengujian lain dapat didasarkan pada tipe lokal yang sekarang diizinkan sebagai argumen template:
sumber
isC++0x
pengenal C ++ yang valid;)Ini bukan contoh yang benar, tetapi ini adalah contoh menarik yang dapat membedakan C vs. C ++ 0x (meskipun C ++ 03 tidak valid):
sumber
sizeof(int) != 1
kebenaran. Pada sistem 0x denganchar
s yang sangat besar , hasilnya bisa sama. Masih trik yang rapi.char
selalu satu bytesizeof(char)
akan selalu 1, menurut definisi. TapiCHAR_BIT
(didefinisikan dalam limit.h) diperbolehkan lebih dari 8. Akibatnya, keduanyachar
danint
bisa memiliki 32 bit, dalam hal inisizeof(int) == 1
(danCHAR_BIT == 32
).Dari pertanyaan ini :
sumber
bool is_cpp0x = !test[0].flag;
T
sedangkan C ++ 03 menyalin konstruksi dariT()
Meskipun tidak begitu ringkas ... Dalam C ++ saat ini, nama template kelas itu sendiri diartikan sebagai nama jenis (bukan nama template) dalam cakupan template kelas tersebut. Di sisi lain, nama template kelas dapat digunakan sebagai nama template di C ++ 0x (N3290 14.6.1 / 1).
sumber
sumber