Ne yazık ki, bir çapraz platformda, çapraz derleyici ortamında, bunu yalnızca derleme zamanında yapmak için tek bir güvenilir yöntem yoktur.
- Proje ayarları hatalı veya bozuksa (özellikle Visual Studio 2008 SP1'de) hem _WIN32 hem de _WIN64 bazen tanımsız olabilir .
- "Win32" etiketli bir proje, bir proje yapılandırma hatası nedeniyle 64-bit olarak ayarlanabilir.
- Visual Studio 2008 SP1'de, intellisense, geçerli #define göre bazen kodun doğru kısımlarını grileştirmez. Bu, derleme zamanında hangi #define kullanıldığını görmeyi zorlaştırır.
Bu nedenle, tek güvenilir yöntem 3 basit kontrolü birleştirmektir :
- 1) Derleme zamanı ayarı ve;
- 2) Çalışma zamanı kontrolü ve;
- 3) Sağlam derleme zamanı kontrolü .
Basit kontrol 1/3: Derleme zamanı ayarı
Gerekli #define değişkenini ayarlamak için herhangi bir yöntem seçin . @JaredPar yöntemini öneririm:
// Check windows
#if _WIN32 || _WIN64
#if _WIN64
#define ENV64BIT
#else
#define ENV32BIT
#endif
#endif
// Check GCC
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENV64BIT
#else
#define ENV32BIT
#endif
#endif
Basit kontrol 2/3: Çalışma zamanı kontrolü
Main () öğesinde sizeof () yönteminin anlamlı olup olmadığını görmek için iki kez kontrol edin:
#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
Basit kontrol 3/3: Sağlam derleme zamanı kontrolü
Genel kural "her #define hata üreten bir #else ile bitmelidir" dir.
#if defined(ENV64BIT)
// 64-bit code here.
#elif defined (ENV32BIT)
// 32-bit code here.
#else
// INCREASE ROBUSTNESS. ALWAYS THROW AN ERROR ON THE ELSE.
// - What if I made a typo and checked for ENV6BIT instead of ENV64BIT?
// - What if both ENV64BIT and ENV32BIT are not defined?
// - What if project is corrupted, and _WIN64 and _WIN32 are not defined?
// - What if I didn't include the required header file?
// - What if I checked for _WIN32 first instead of second?
// (in Windows, both are defined in 64-bit, so this will break codebase)
// - What if the code has just been ported to a different OS?
// - What if there is an unknown unknown, not mentioned in this list so far?
// I'm only human, and the mistakes above would break the *entire* codebase.
#error "Must define either ENV32BIT or ENV64BIT"
#endif
Güncelleme 2017-01-17
Yorum yapan @AI.G
:
4 yıl sonra (daha önce mümkün olup olmadığını bilmiyorum) çalışma zamanı kontrolünü statik assert kullanarak derleme zamanı kontrolüne dönüştürebilirsiniz: static_assert (sizeof (void *) == 4) ;. Şimdi her şey derleme zamanında yapılır :)
Ek Bölüm A
Gizli olarak, yukarıdaki kurallar tüm kod tabanınızı daha güvenilir hale getirmek için uyarlanabilir:
- Her if () ifadesi, uyarı veya hata oluşturan bir "else" ile biter.
- Her switch () ifadesi, bir uyarı veya hata oluşturan bir "default:" ile biter.
Bunun iyi çalışmasının nedeni, sizi her bir vakayı önceden düşünmeye ve doğru kodu yürütmek için "başka" kısımdaki (bazen hatalı) mantığa güvenmemeye zorlamasıdır.
Bu tekniği (diğerlerinin yanı sıra) ilk üretime verildiği günden (12 ay önce) 30.000 satırlık bir proje yazmak için kullandım.