Sayangnya, dalam lingkungan lintas platform, lintas kompiler, tidak ada satu metode yang dapat diandalkan untuk melakukan ini murni pada waktu kompilasi.
- Baik _WIN32 dan _WIN64 terkadang keduanya tidak ditentukan, jika pengaturan proyek cacat atau rusak (terutama pada Visual Studio 2008 SP1).
- Proyek berlabel "Win32" dapat disetel ke 64-bit, karena kesalahan konfigurasi proyek.
- Pada Visual Studio 2008 SP1, terkadang intellisense tidak mengubah bagian kode yang benar, menurut #define saat ini. Ini menyulitkan untuk melihat dengan tepat #define mana yang digunakan pada waktu kompilasi.
Oleh karena itu, satu - satunya metode yang dapat diandalkan adalah menggabungkan 3 pemeriksaan sederhana :
- 1) Menyusun pengaturan waktu , dan;
- 2) Pemeriksaan runtime , dan;
- 3) Pemeriksaan waktu kompilasi yang kuat .
Pemeriksaan sederhana 1/3: Kompilasi pengaturan waktu
Pilih metode apa pun untuk menyetel variabel #define yang diperlukan. Saya menyarankan metode dari @JaredPar:
#if _WIN32 || _WIN64
#if _WIN64
#define ENV64BIT
#else
#define ENV32BIT
#endif
#endif
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENV64BIT
#else
#define ENV32BIT
#endif
#endif
Pemeriksaan sederhana 2/3: Pemeriksaan waktu proses
Di main (), periksa kembali untuk melihat apakah sizeof () masuk akal:
#if defined(ENV64BIT)
if (sizeof(void*) != 8)
{
wprintf(L"ENV64BIT: Error: pointer should be 8 bytes. Exiting.");
exit(0);
}
wprintf(L"Diagnostics: we are running in 64-bit mode.\n");
#elif defined (ENV32BIT)
if (sizeof(void*) != 4)
{
wprintf(L"ENV32BIT: Error: pointer should be 4 bytes. Exiting.");
exit(0);
}
wprintf(L"Diagnostics: we are running in 32-bit mode.\n");
#else
#error "Must define either ENV32BIT or ENV64BIT".
#endif
Pemeriksaan sederhana 3/3: Pemeriksaan waktu kompilasi yang kuat
Aturan umumnya adalah "setiap #define harus diakhiri dengan #else yang menghasilkan kesalahan".
#if defined(ENV64BIT)
#elif defined (ENV32BIT)
#else
#error "Must define either ENV32BIT or ENV64BIT"
#endif
Perbarui 2017-01-17
Komentar dari @AI.G
:
4 tahun kemudian (tidak tahu apakah itu mungkin sebelumnya) Anda dapat mengubah pemeriksaan run-time menjadi waktu kompilasi menggunakan statik assert: static_assert (sizeof (void *) == 4) ;. Sekarang semuanya selesai pada waktu kompilasi :)
Lampiran A
Secara tidak langsung, aturan di atas dapat disesuaikan untuk membuat seluruh basis kode Anda lebih andal:
- Setiap pernyataan if () diakhiri dengan "else" yang menghasilkan peringatan atau kesalahan.
- Setiap pernyataan switch () diakhiri dengan "default:" yang menghasilkan peringatan atau kesalahan.
Alasan mengapa ini bekerja dengan baik adalah karena ini memaksa Anda untuk memikirkan setiap kasus terlebih dahulu, dan tidak mengandalkan logika (terkadang cacat) di bagian "lain" untuk menjalankan kode yang benar.
Saya menggunakan teknik ini (di antara banyak lainnya) untuk menulis 30.000 proyek garis yang bekerja dengan sempurna sejak pertama kali digunakan dalam produksi (itu 12 bulan yang lalu).