0

Edit: Stupid question, I overlooked the format identifiers.

I had a program grab the size of a few unsigned types and their maximum value. This brought an anomaly to my attention, the fact that even thought unsigned long long is 8 bytes, it's range seems to be fixed to a 4 byte range. (char is a guaranteed 8-bit byte)

Question
I understand that unsigned long long is only defined by the standards to be at least large enough to hold an int (or rather >= long int >= int transitively). However, why is it using 8 bytes of memory instead of being the same size as int if it's limited to the range of 4 bytes too?

unsigned char:             255         1*sizeof(char)           
unsigned short:            65535       2*sizeof(char)        
unsigned short int:        65535       2*sizeof(char)       
unsigned int:              4294967295  4*sizeof(char)            
unsigned long int:         4294967295  4*sizeof(char)            
unsigned long long int:    4294967295  8*sizeof(char)  //range[0..18446744073709551615]       
unsigned long:             4294967295  4*sizeof(char)            
unsigned long long:        4294967295  8*sizeof(char)  //range[0..18446744073709551615]

Here is the source I used:

#include <iostream>
#include <cstdio>

int main(void){

    std::cout << "Type sizes: (multiples of char)"<< std::endl << "char: " << sizeof(char) << std::endl <<\
    "short: " << sizeof() << std::endl <<\
    "short int: " << sizeof(short int) << std::endl << std::endl <<\
    "int: " << sizeof(int) << std::endl <<\
    "long int: " << sizeof(long int) << std::endl <<\
    "long long int: " << sizeof(long long int) << std::endl << std::endl <<\
    "long: " << sizeof(long) << std::endl <<\
    "long long: " << sizeof(long long) << std::endl << std::endl <<\
    "float: " << sizeof(float) << std::endl <<\
    "double: " << sizeof(double) << std::endl;

    unsigned char c = -1;
    unsigned short s1 = -1;
    unsigned short int s2 = -1;

    unsigned int i = -1;
    unsigned long int i1 = -1;
    unsigned long long int i2 = -1;

    unsigned long l = -1;
    unsigned long long l1 = -1;

    printf("\
            \nUnsigned Max:     \n\
            \nchar:             %u\
            \nshort:            %u\
            \nshort int:        %u\
            \nint:              %u\
            \nlong int:         %u\
            \nlong long int:    %u\
            \nlong:             %u\
            \nlong long:        %u\
            ", c, s1, s2, i, i1, i2, l, l1);

    return 0;
}
effeffe
  • 2,821
  • 3
  • 21
  • 44
GRAYgoose124
  • 621
  • 5
  • 24
  • 1
    I think your test is broken. "unsigned long long" is guaranteed to go up to at least 2^64 - 1. – Kyurem Apr 26 '13 at 17:54
  • @Kyurem I edited the code that I used to test it into the question. I believe the problem may actually be in that I tested it on ideone.com. Edit, you're right, I was using the wrong format token and didn't check it. – GRAYgoose124 Apr 26 '13 at 17:58
  • 1
    The standard requires `long long int` to be at least 64 bits. (In principle, a byte can be wider than 8 bits, but you're likely to see `CHAR_BIT>8` only on [DSPs](http://en.wikipedia.org/wiki/Digital_signal_processor). – Keith Thompson Apr 26 '13 at 21:00
  • all those backslashes at the end of each line is redundant, because C++ simply ignore newlines and just take `;` as statement separator – phuclv Sep 07 '17 at 01:04
  • Possible duplicate of [What happens when I use the wrong format specifier?](https://stackoverflow.com/questions/16864552/what-happens-when-i-use-the-wrong-format-specifier) – phuclv Sep 07 '17 at 01:06

1 Answers1

1

You're using the wrong flag for printf, the values are actually alright but printf isn't displaying them correctly. Try %llu for unsigned long long.

More info on printf (flags): http://www.cplusplus.com/reference/cstdio/printf/

Kninnug
  • 7,992
  • 1
  • 30
  • 42