Слияние типов в Си
2025-05-13 21:56Согласно грамматике, в Си можно писать: 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` не могут повторяться.

no subject
Date: 2025-05-14 07:51 (UTC)no subject
Date: 2025-05-14 23:19 (UTC)no subject
Date: 2025-05-14 08:50 (UTC)no subject
Date: 2025-05-14 23:19 (UTC)no subject
Date: 2025-05-15 11:41 (UTC)Я бы на Хаскелѣ писалъ вмѣсто C. Вотъ сейчасъ я думаю начать новый хобби-проектъ. Выборъ языка, на мой взглядъ, однозначенъ - или Скала или Хаскель или оба вмѣстѣ параллельно. Даже въ голову не пришло бы дѣлать что-то на С. Это же 50 лѣтъ уже прошло, а тамъ до сихъ поръ header files, и #include header files просто текстуально вставляется...
_Bool несовместимо ...
Date: 2025-05-14 09:00 (UTC)Потому как стандарт не определяет для данных этого типа ни размер ни правила выравнивания.
Но зато в каждом коллективе есть кучка деятелей, которые этот тип используют везде,
плодя со страшной скоростью лохматые структуры с дырками, которые разные из-под разных компиляторов,
или из-за разных флагов компиляции.
no subject
Date: 2025-05-14 23:25 (UTC)no subject
Date: 2025-05-14 11:49 (UTC)no subject
Date: 2025-05-14 23:29 (UTC)no subject
Date: 2025-05-14 13:06 (UTC)заметьте, что они все прилагательные
то есть можно, собирая определение типа по токенам
- short / long класть в модификаторы, остальное в типы
- сочетание модификаторов short short запрещено, long long разрешено, long short запрещено, 3 модификатора ошибка
в конце
- если тип не указан, то примитивный тип = инт
- модификатор long можно ещё применить к double, если что иное -- ошибка
ни у вас, ни у меня неясно, имеют ли смысл long char / short char -- может типа wchar_t?
no subject
Date: 2025-05-14 23:38 (UTC)Float, double, _Complex и _Imaginary тоже прилагательные, но плохо прилагаются. 😀
_Complex int не напишешь. Хотя математически почему бы и нет.
На мой взгляд логично было бы сделать long char вместо wchar_t. Не знаю почему так решили.
no subject
Date: 2025-05-14 14:26 (UTC)Совместимость зависит от базового типа (например, если `MyType` - это `int`, он ведет себя как `int`).
Когда в ИИшнице согласья нет, на лад её дело не пойдёт.
no subject
Date: 2025-05-14 23:41 (UTC)Арифметическая совместимость - да, определяется базовым типом.
Но к синтаксической совместимости базовый тип не имеет отношения.