Существует ли гибрид C и C#?
После C# переход на C слегонца фрустрирует. Дело не в сборке мусора, LINQ и метапрограммировании с компонентной моделью, которое я люблю использовать при программировании на C#. Понятно, что этого в C быть и не должно, не для тех целей язык. Дело в том, что в C# решены некоторые проблемы, которые можно было бы решить и в C, не меняя его идеологии. Может, существует такой компромиссный язык?
Что мне не нравится в C:
- C разрешает обращаться к неинициализированным переменным.
- В C не отследить арифметическое переполнение (правда, можно для этого сделать ассемблерную вставку, но она срабатывает только тогда, когда переполнение происходит в последней операции перед ассемблерной вставкой).
- C разрешает писать функции, которые, хотя и должны возвращать значение, могут его не возвращать.
- Не уверен, что это возможно в рамках архитектуры C, но хорошо бы иметь возможность всегда узнать длину массива, а не только когда он создан в стеке в пределах функции.
- C разрешает проваливание в операторах
switch
после того, как по константе выполнились какие-нибудь инструкции. - Неудобный синтаксис для указателей на функцию. Я не представляю себе, как с помощью такого синтаксиса можно описать функцию, которая возвращает указатель на функцию, которая принимает или возвращает указатель на функцию.
- При объявлении функций с переменным числом параметров не указывается тип этих параметров. Хотелось бы, чтобы опционально такая возможность была (в C# эта опциональность достигается наличием типа
object
). Да и сишный способ разбора этих параметров не отличается прозрачностью. Если бы функциюscanf
можно было бы объявить как-нибудь так:scanf(const char*, params void*[] p);
, то можно было бы проверить на этапе компиляции, что ей переданы именно адреса, а не непонятно что. - Синтаксис объявления переменных и формальных параметров функций в C неудачный, типы перемешаны с переменными (например,
int i, j[10], *p;
). Полагаю, неудобства в работе с указателями на функцию и переменным числом параметров растут оттуда. - В C имеет место некоторый бардачок с целочисленными типами данных. Мне нравится, что в C# каждый целочисленный тип называется строго одним ключевым словом, и нет чехарды с тем, что такое int: двух- или четырёхбайтное целое.
- Ещё меня смущает адресная арифметика. Мне кажется, указатели надо было сделать неизменяемыми: мы получили некоторый адрес путём & или malloc, и дальше менять его всякими инкрементами не можем. Если хотим изменить значение указателя с помощью адресной арифметики, мы должны создать новый указатель.
- Очень бесит, что нельзя объявить переменную цикла при объявлении цикла. Правда, в C++ вроде бы уже можно.
- При работе с перечислениями значения указываются без префикса типа перечисления, с префиксом было бы нагляднее.
- Непонятно, зачем при объявлении перечисления или структуры без
typedef
при использовании этих типов надо писатьstruct ADDRESS
илиenum week_day
вместо простоADDRESS
илиweek_day
. - При работе с битовыми полями хорошо бы было более чётко специфицировать порядок выделения бит. Например, с помощью дополнительной конструкции (типа того, что пишем после точки не только количество бит, но и номер, с которого начинаем).
- При работе с перечислениями базовый числовой тип не указывается явно, только по используемым значениям перечисления.