Malheureusement, il n'existe pas de méthode fiable pour ce faire purement au moment de la compilation.
- Les deux _WIN32 et _WIN64 peut parfois les deux être indéfini, si les paramètres du projet sont défectueux ou endommagé (notamment sur Visual Studio 2008 SP1).
- Un projet labellisé "Win32" pourrait être fixé à 64 bits, en raison d'un projet d'erreur de configuration.
- Sur Visual Studio 2008 SP1, parfois, l'intellisense ne pas gris, les parties appropriées du code, en fonction du courant #define. De ce fait, il est difficile de voir exactement ce qui #define est utilisé au moment de la compilation.
Par conséquent, la seule fiable de la méthode est de combiner 3 vérifications simples:
- 1) la Compilation de réglage de l'heure, et;
- 2) le moment de l'Exécution, et;
- 3) Robuste moment de la compilation, la vérification.
Simple de vérifier 1/3: Compilation de réglage de l'heure
Choisir une méthode pour définir les requis #define variable. Je vous propose la méthode de @JaredPar:
// 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
Simple de vérifier 2/3: moment de l'Exécution
Dans main(), vérifiez pour voir si sizeof() prend tout son sens:
#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
Vérification Simple 3/3: Robuste moment de la compilation, la vérification de
La règle générale est "tous les #define doit se terminer dans un #else qui génère une erreur".
#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
L'Annexe A
Incidentially, les règles ci-dessus peut être adapté pour faire de l'ensemble de votre base de code plus fiable:
- Chaque instruction if() se termine par un "autre" qui génère un avertissement ou d'erreur.
- Chaque instruction switch() se termine par un "défaut:" qui génère un avertissement ou d'erreur.
La raison pour laquelle cela fonctionne bien, c'est qu'il vous oblige à penser à tous les cas à l'avance, et ne pas compter sur la (parfois erronées) logique dans le "else" de la partie à exécuter le code correct.
J'ai utilisé cette technique (parmi beaucoup d'autres) d'écrire une ligne de 160 000 projet qui n'a jamais écrasé dans la production au cours des 12 mois de fonctionnement en continu.