Слияние типов в Си
2025-05-13 21:56![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Согласно грамматике, в Си можно писать: signed short int. Причём в любом порядке. А можно char char char char char. Первое правильно, второе неправильно. Можно писать long long но нельзя shоrt short. Можно long double но нельзя short float. Существуют определённые правила, по которым длинная последовательность элементарных спецификаторов типа сливается в один правильный тип. Или отвергается как неверная. Вот таблица совместимости типов. Я убрал отсюда _Atomic, с ним совсем сложно и лучше рассматривать отдельно.
Заметки о конкретных комбинациях:
void char short int long float double signed unsigned _Bool _Complex _Imaginary struct union enum MyType
--------------------------------------------------------------------------------------------------------------------
void ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
char ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗
short ✗ ✗ ✗ ✓ ✗ ✗ ✗ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗
int ✗ ✗ ✓ ✗ ✓ ✗ ✗ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗
long ✗ ✗ ✗ ✓ ✓ ✗ ✓ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗
float ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✓ ✓ ✗ ✗ ✗ ✗
double ✗ ✗ ✗ ✗ ✓ ✗ ✗ ✗ ✗ ✗ ✓ ✓ ✗ ✗ ✗ ✗
signed ✗ ✓ ✓ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
unsigned ✗ ✓ ✓ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
_Bool ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
_Complex ✗ ✗ ✗ ✗ ✗ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
_Imaginary ✗ ✗ ✗ ✗ ✗ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
struct ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
union ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
enum ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
MyType ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
void
- Несовместимо со всеми другими спецификаторами, так как `void` является отдельным типом.
- Пример: `void int` недопустимо.
char, short, int, long
- Совместимо с `signed`, `unsigned` (например, `unsigned char`, `signed long`).
- `short` и `int` объединяются как `short int`.
- `long` и `int` объединяются как `long int`.
- `long` может объединяться с `double` (`long double`) и самим собой (`long long`).
- Несовместимо с `float`, `double`, `_Complex`, `_Imaginary`, `struct`, `union`, `enum`, `MyType`.
float, double
- Совместимо с `_Complex`, `_Imaginary` (например, `float _Complex`, `double _Imaginary`).
- `double` с `long` образует `long double`.
- Несовместимо с `signed`, `unsigned`, целочисленными типами, `struct`, `union`, `enum`, `MyType`.
signed, unsigned
- Применяется к `char`, `short`, `int`, `long` (например, `unsigned short`).
- `signed` подразумевается для `int`, если он один.
- Несовместимо с `float`, `double`, `_Bool`, `_Complex`, `_Imaginary`, `struct`, `union`, `enum`, `MyType`.
_Bool
- Несовместимо со всеми другими спецификаторами.
_Complex, _Imaginary
- Сочетается с `float`, `double` (например, `float _Complex`).
- Несовместимо с целочисленными типами, `_Bool`, `struct`, `union`, `enum`, `MyType`.
struct, union, enum
- Несовместимо с базовыми типами, `signed`, `unsigned`, `_Complex`, `_Imaginary`, `MyType`.
MyType (typedef)
- Представляет определенный пользователем тип (например, `typedef int MyType`).
- Несовместимо с другими спецификаторами, так как это полный тип.
- Совместимость зависит от базового типа (например, если `MyType` - это `int`, он ведет себя как `int`).
Самосочетания
- Большинство спецификаторов не могут сочетаться друг с другом (например, `int int` недопустимо).
- `long` является исключением: `long long` допустимо.
- `struct`, `union`, `enum`, `MyType` не могут повторяться.