%ld conversion de format pour la portabilité
J'ai une base de code qui est destiné à compiler sans les avertissements et les exécuter sans aucun problème sur plusieurs architectures, toutes x86: MS-dos, Windows 32 mode console, Windows 32 en mode graphique, Linux 32 et Linux 64.
Avant d'ajouter le support de Linux 64, c'était facile. Presque toutes les données ont été déclarées, soit comme int
ou de les typedefs de type BYTE, WORD, DWORD:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
Lors de l'ajout de 64 bits gcc soutien, DWORD besoin d'un peu de peaufinage de rester comme une valeur 32 bits puisqu'il représente les données stockées:
//to compile DWORDs as 32 bits on 64-bit machines:
#if __x86_64__
typedef unsigned int DWORD;
#else
typedef unsigned long DWORD;
#endif
Et cela a fonctionné à merveille sur tous les environnements:
DWORD data;
printf ("%lu", data);
Cependant, gcc -Wall
maintenant se plaint des conversions de format:
warning: format ‘%ld’ expects argument of type ‘long int’, but argument
1 has type ‘DWORD {aka unsigned int}’ [-Wformat]
En raison de la mise en forme de ce code n'—des milliers de lignes de sortie de mise en forme, je préfère ne pas la modernisation d'un type spécifique de formateur. Une question semblable a été répondu en utilisant le z
modificateur:
printf ("%zu", data);
Mais qui fait de Turbo C sur MS-dos et Win32 console de faire quelque chose de bizarre: Il montre la spécification de conversion %zu
en sortie au lieu de convertir quoi que ce soit.
Est-il le moyen le plus propre pour gérer la variabilité du type d'une façon qui va de pair avec le grain de printf et des types de données?
OriginalL'auteur wallyk | 2013-06-05
Vous devez vous connecter pour publier un commentaire.
Je pense que votre moins mauvaise solution possible est d'emprunter, conceptuellement, de
<inttypes.h>
:et puis
Cela rend l'utilisation de la constante de chaîne de concaténation, qui tous C90-conforme compilateurs doit prendre en charge. Notez que la macro appropriée pour le test est
_LP64
, pas__x86_64__
; de cette façon, il sera à peu de Travail quand vous allez à port à un autre LP64 système, ou le tout nouveau "x32" mode de Linux/x86-64 (pointeurs 32 bits, échelle de registres).Il serait peut-être pas une mauvaise idée d'investir dans un gros conversion à l'
<stdint.h>
types, mais qui ne sera pas vous sortir de ce genre de chose, vous devriez juste être écritau lieu de cela, et pour autant que je sais que la plupart des compilateurs pour Windows encore n'ont pas
<inttypes.h>
, soupir.Dans le cas où vous poseriez la question, le
%
n'est pas à l'intérieur de la macro de sorte que vous pouvez mettre format ajusteurs, si vous voulez:int
oulong
. Il n'y a que quelques centaines qui ne sont pas si facilement générique, donc je vais les changer de format avec%s
et une main pleine de conversion aux fonctions de chaîne, surchargé sur le type d'argument.OriginalL'auteur zwol