13

We use template specialization for some type parameter like

class my_template_class<uint64_t M>: public my_template_class_base<uint64_t> {
 ....
}

class my_template_class<unsigned long long,M>: public my_template_class_base<unsigned long long> {
 ....
}

This is working perfectly with 64-bit compilation with gcc. While when we try the 32 bit mode, it reports "previous definition" for above two classes.

So unsigned long long is the same as uint64_t in the 32-bit compilation but not in 64-bit compliation?

The compilation difference is the CXX flag -m32 and -m64

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
thundium
  • 995
  • 4
  • 12
  • 30
  • 5
    @FrédéricHamidi: Unlikely; I've never seen a system with a 128-bit `unsigned long long`. – Keith Thompson Aug 25 '15 at 07:54
  • What does uint64_t actually compile to? I don't have GCC handy but you could check the stdint header. Would probably give some clues as to what the compiler actually sees. – BlamKiwi Aug 25 '15 at 07:55
  • 1
    I'm pretty sure that on a 64 bit platform, `uint64_t` is defined as `unsigned long`, and thus does not conflict with `unsigned long long`, while on a 32 bits platform, `uint64_t` must be `unsigned long long`, yielding your error – NiBZ Aug 25 '15 at 07:57
  • @NiBZ wrong. Windows uses [LLP64 model](https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models), hence even on 64-bit Windows, long is still 32 bits and `uint64_t` must be defined to `unsigned long long` – phuclv Aug 25 '15 at 08:14
  • @LưuVĩnhPhúc As the OP mentioned gcc in his message, I assumed that he was building on an Unix-like platform (which are LP64). Should've mentioned it in my post. – NiBZ Aug 25 '15 at 08:19
  • @NiBZ gcc on Windows will follow Windows model – phuclv Aug 25 '15 at 08:21
  • Presumably all the `M`'s are typos – M.M Aug 25 '15 at 09:04
  • The duplicate question was about _signed_ long, but otherwise essentially the same. – MSalters Aug 25 '15 at 09:49

2 Answers2

25

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.

In 32-bit mode, the compiler (more precisely the <stdint.h> header) defines uint64_t as unsigned long long, because unsigned long isn't wide enough.

In 64-bit mode, it defines uint64_t as unsigned long.

It could have defined it as unsigned long long in both modes. The choice is arbitrary; all that's required is that it has to be a 64-bit type.

In general, each of the integer types defined in <stdint.h> is a typedef for some predefined type with the appropriate characteristics. You can't assume that any of them are distinct from the predefined types.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • On Windows `uint64_t` must be defined as `unsigned long long` as long is only 32 bits https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models – phuclv Aug 25 '15 at 08:16
  • @LưuVĩnhPhúc: It's been defined as `__uint64` in the past. It's generally unspecified whether two types with identical representation are in fact the same type; the exception being `char` versus `signed char` or `unsigned char` for which it's defined that these constitute 3 types and 2 representations. – MSalters Aug 25 '15 at 09:52
  • @MSalters: To be clear, all the predefined types are distinct, regardless of their representation. For example, `int` and `long` are distinct types even if they have the same size and representation. If you're referring to types defined in the standard headers, like `int32_t`, you're right. – Keith Thompson Aug 10 '17 at 02:30
8

This is from stdint.h for GCC 4.8:

#if __WORDSIZE == 64
typedef unsigned long int   uint64_t;
#else
__extension__
typedef unsigned long long int  uint64_t;
#endif

So:

So unsigned long long is the same as uint64_t in the 32bit compliation but not in 64 bit compliation?

Yes.

Paolo M
  • 12,403
  • 6
  • 52
  • 73
  • 2
    Yes, for GCC. Don't assume it's true everywhere. Visual Studio for instance has an unconditional `typedef unsigned long long uint64_t;` – MSalters Aug 25 '15 at 10:05