2011-03-24 4 views
3

Je rencontre un problème avec la façon dont MSVC gère les entiers longs non signés. Voici ce code pour reproduire:MSVC++ de manutention unsigned long long int

// test.cpp (note extension) 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) { 
    unsigned long long int address = 0x0A0B0C0D0E0F; 
    printf("Address=%llu\n", address); 

    printf("%02X:%02X:%02X:%02X:%02X:%02X\n", 
      ((address >> (5 * 8)) & 0xff), 
      ((address >> (4 * 8)) & 0xff), 
      ((address >> (3 * 8)) & 0xff), 
      ((address >> (2 * 8)) & 0xff), 
      ((address >> (1 * 8)) & 0xff), 
      (address & 0xff)); 

    printf("%02X:", ((address >> (5 * 8)) & 0xff)); 
    printf("%02X:", ((address >> (4 * 8)) & 0xff)); 
    printf("%02X:", ((address >> (3 * 8)) & 0xff)); 
    printf("%02X:", ((address >> (2 * 8)) & 0xff)); 
    printf("%02X:", ((address >> (1 * 8)) & 0xff)); 
    printf("%02X\n", (address & 0xff)); 

    exit(0); 
} 

Quand je compile cela sur linux, je reçois (comme prévu):

Address=11042563100175 
0A:0B:0C:0D:0E:0F 
0A:0B:0C:0D:0E:0F 

Cependant, quand je compile cela sur MSVC++ 2008 Express Je reçois:

Address=11042563100175 
0A:00:0B:00:0C:00 
0A:0B:0C:0D:0E:0F 

Est-ce que j'ai mal formaté mon instruction printf? Ou MSVC laisse-t-il un octet supplémentaire sur la pile après le changement/et les opérations? Ou est le problème avec quelque chose d'autre?

Remarque: lors de la compilation avec MSVC, vous devez utiliser l'extension de fichier '.cpp' pour forcer le mode C++. Je crois que c'est parce que MSVC en mode C droit n'inclut pas (tout de) C99 qui inclut le drapeau '% llu' pour printf.

Simon.

+0

Hmm. Il semble que la gestion de la pile MSVC dans printf est en effet le problème. Dans ce cas, il ne sort qu'un seul long de la pile, laissant l'autre moitié du long restant. Casting à int semble résoudre le problème. – Simon

+0

Ce n'est pas un problème, c'est un comportement correct. 'printf' est une fonction varargs, vous en tant que programmeur êtes responsable de la sécurité de type. Le spécificateur de format '% X' promet un' int', en passant un 'unsigned long long' à la place, tous les paris sont désactivés. –

Répondre

5

Le spécificateur de format% X attend un argument de 32 bits. Vous passez 64 bits, jetant la pile. Vous pouvez utiliser% llX. Le CRT est le même pour les codes C et C++.

Questions connexes