Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type of unsigned long is different from uint32_t and uint64_t on Windows (VS2010)

On Visual Studio 2010 under Windows 7, 32bit, unsigned long seems to be a distinct type from both uint32_t and uint64_t. See the following test program:

#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;
}

I'd expect it to print either

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

(which I get on x86_64 Linux) or

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

assuming of course that long is not longer than 64bits.

On Windows however, I get the baffling

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

which means that there are two distinct 32bit unsigned types. Is this allowed by the C++ standard? Or is this a bug in the Visual C++ compiler?

like image 387
tbleher Avatar asked Jul 23 '12 11:07

tbleher


People also ask

Is unsigned long the same as uint32_t?

Type of unsigned long is different from uint32_t and uint64_t on Windows (VS2010) Bookmark this question. Show activity on this post. assuming of course that long is not longer than 64bits.

Is unsigned long long same as uint64_t?

So unsigned long long is the same as uint64_t in the 32-bit compilation but not in 64-bit compilation? Yes. In 32-bit mode, most likely long is 32 bits and long long is 64 bits. In 64-bit mode, both are probably 64 bits.

What is the difference between unsigned int and unsigned long?

Unsigned int is only guaranteed to be able to hold the numbers between 0 and 65535 (inclusive), while unsigned long int is guaranteed to be able to hold the numbers between 0 and 4 294 967 295. Those are just the minimums, though.

What is the difference between uint32 and uint32_t?

typedef unsigned integer type uint32_t; // optional //... } uint32 is not, it's a shortcut provided by some compilers (probably as typedef uint32_t uint32 ) for ease of use. More likely as a typedef for something that was known to be an unsigned 32 bit integer at a time before <cstdint> was standard.


1 Answers

There are two distinct 32-bit, unsigned types

Yes, there are. Both int and long are represented by 32 bits.

Is this allowed by the C++ standard?

Yes. The specification states (C++11 §3.9.1[basic.fundamental]/2):

There are five standard signed integer types : signed char, short int, int, long int, and long long int. In this list, each type provides at least as much storage as those preceding it in the list.

For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type...each of which occupies the same amount of storage and has the same alignment requirements as the corresponding signed integer type

Note that despite the fact that int and long are represented by the same number of bits, they are still different types (so, for example, they are treated differently during overload resolution).

like image 193
James McNellis Avatar answered Oct 12 '22 11:10

James McNellis