Type de unsigned long est différente de uint32_t et un uint64_t sur Windows (VS2010)

Sur Visual Studio 2010 sous Windows 7, 32 bits, unsigned long semble être un type distinct de deux uint32_t et un uint64_t. Voir le programme de test suivant:

#include <stdint.h>
#include <stdio.h>

template<class T, class U>
struct is_same_type
{
    static const bool value = false;
};
template<class T>
struct is_same_type<T, T>
{
    static const bool value = true;
};

#define TO_STRING(arg)        TO_STRING_IMPL(arg)
#define TO_STRING_IMPL(arg)   #arg

#define PRINT_SAME_TYPE(type1, type2) printf("%s (size=%d) %s %s (size=%d)\n", \
    TO_STRING(type1), int(sizeof(type1)), \
    is_same_type<type1, type2>::value ? "==" : "!=", \
    TO_STRING(type2), int(sizeof(type2)))


int main(int /*argc*/, const char* /*argv*/[])
{
    PRINT_SAME_TYPE(uint32_t, unsigned long);
    PRINT_SAME_TYPE(uint64_t, unsigned long);
    return 0;
}

Je m'attends à imprimer soit

uint32_t (size=4) != unsigned long (size=8)
uint64_t (size=8) == unsigned long (size=8)

(que je reçois sur Linux x86_64) ou

uint32_t (size=4) == unsigned long (size=4)
uint64_t (size=8) != unsigned long (size=4)

en supposant bien sûr que longue n'est pas plus long que 64bits.

Sur Windows cependant, j'ai l'déconcertant

uint32_t (size=4) != unsigned long (size=4)
uint64_t (size=8) != unsigned long (size=4)

ce qui signifie qu'il y a deux distincts 32 bits non signé types. Est-ce autorisé par la norme C++? Ou est-ce un bug du compilateur Visual C++?

Oui, il y a deux distincts, non signé non signé de 32 bits types. uint32_t est un typedef unsigned int. Et unsigned int != unsigned long.

OriginalL'auteur tbleher | 2012-07-23