Процессоры развивались постепенно все более расширяя емкость регистров. Например, ранее в DOS тип int соответствовал 16 разрядному целочисленному значению, так как на IBM-совместимых компьютеров регистры были 16-разрядными. Например, регистр AX является 16 разрядным, а его подрегистры AL и AH имели разрядность равную 8 битам. До этого вообще регистры процессоров были 8 разрядными.
Если выполнить, допустим, умножение двух объектов 16-разрядного типа int, то для хранения результата нужно использовать два регистра как, например, регистры AX и DX. Для этого результата уже нужно вводить новый целочисленный тип. И такой тип был введен. Это тип long .
Затем появились 64-разрядные процессоры. Необходимо различать 16-разрядные целые числа, 32-разрядные целые числа и 64- разрядные целые числа. Поэтому был введен дополнительный целый тип Long long. Имейте в виду, что нужно было сохранять обратную совместимость с целыми типами, введенными ранее для процессоров с меньшей разрядностью.
Поэтому в стандарте C принято, что
sizeof( short ) <= sizeof( int )
sizeof( int ) <= sizeof( long )
sizeof( long ) <= sizeof( long long )
У разработчиков компиляторов есть свобода выбора, какая разрядность будет у типа long и других целочисленных типов. Например, разрядность типа long может составлять не `32 бита, а 64 бита.
Чтобы программы были переносимы, возникла необходимость вводить новые типы со строго указанной разрядностью такие, как, например, int_least32_t или int32_t.
На одних 64-битовых платформах тип long и тип long long могут иметь 64-битовуж разрядность. На других 64-битовых платформах тип long может быть 32-битовым и тип int также может быть 32-битовым, а тип long long - 64 битовым.
Тем не менее ранг типа long long больше ранга типа long, а тип long в свою очередь имеет ранг выше, чем тип int.
На этом основываются правила преобразования типов в выражениях. Например, если тип long и тип int имеют разрядность равную 32 битам, то в следующем фрагменте кода
long x = 0;
unsigned int y = 0;
x + y;
тип выражения x + y имеет тип unsigned long.
В связи с этим имеются некоторые курьезы, связанные с такими преобразованиями особенно при выборе перегруженной функции в C++.
Один из таких примеров описан в следующей теме, где ближе к ее концу (можно быстро найти это сообщение по ключевому слову int64_t) описывается один из таких курьезов, связанных с вызовом перегруженной функции, у которой параметр имеет тип std::int64_t, который, как оказалось, является не алиасом типа long long int, а алиасом типа long int, который на данной платформе является 64-битовым.
очевидно, что на распространенных пользовательских платформах, которые средний по больнице Вася встречает чаще всего-- не, не на распространенных пользовательских, а на правильных (а наиболее распространенная винда к ним не относится) – avp Feb 14 '17 at 13:11