longи long intидентичны. Так long longи есть long long int. В обоих случаях intопционально.
Что касается различия между двумя наборами, стандарт C ++ предписывает минимальные диапазоны для каждого, и это long long, по крайней мере, так же широко, как long.
Контролирующие части стандарта (C ++ 11, но это было давно), например 3.9.1 Fundamental types, раздел 2 (в следующем разделе приведены аналогичные правила для целых типов без знака):
Существует пять стандартных целочисленных типов со знаком: char со знаком, short int, int, long int и long long int. В этом списке каждый тип обеспечивает как минимум столько же памяти, сколько предшествует ему в списке.
Также есть таблица 9 7.1.6.2 Simple type specifiers, которая показывает «сопоставления» спецификаторов с реальными типами (показывая, что intэто необязательно), раздел которых показан ниже:
Specifier(s) Type
------------- -------------
long long int long long int
long long long long int
long int long int
long long int
Обратите внимание на различие между спецификатором и типом. Спецификатор - это то, как вы сообщаете компилятору, что это за тип, но вы можете использовать разные спецификаторы, чтобы получить один и тот же тип.
Следовательно, сам longпо себе не является ни типом, ни модификатором, как предполагает ваш вопрос, это просто спецификатор для long intтипа. То же long longсамое для спецификатора long long intтипа.
Хотя сам стандарт C ++ не определяет минимальные диапазоны целочисленных типов, он ссылается на C99 в 1.2 Normative referencesкачестве применяемого. Следовательно, минимальные диапазоны, изложенные в C99 5.2.4.2.1 Sizes of integer types <limits.h>, применимы.
С точки зрения long double, это на самом деле значение с плавающей запятой, а не целое число. Как и в случае целочисленных типов, требуется иметь как минимум такую же точность, как и, doubleи предоставлять надмножество значений для этого типа (то есть, по крайней мере, те значения, а не обязательно больше значений).