Пост навеян флеймообразующей статьей с Хабра под названием "Как Мэтт Годболт «продал» мне Rust (рассказав о C++)" (которая является переводом статьи Matt Godbolt sold me on Rust (by showing me C++)). Сама статья мне не нравится тем, что на C++ навешивают собак, унаследованных из чистого Си. Да еще и демонстрируют использование приемов, за применение которых в коде надо бы отрывать руки (я про вызов atoi для выделения числа из строки).
Однако, не смотря на то, что неявное преобразование разных целочисленных типов между собой C++ унаследовал из Си и ругать за это безобразие прежде всего следует Си, эта проблема актуальна для C++ного кода. Что лично мне сильно не нравится и о чем я уже не раз говорил.
А раз проблема для C++ актуальна, то было бы хорошо ее решить.
Внезапно™ подумалось, что сделать это может быть не так уж и сложно.
Нужно ввести новые стандартные типы:
- std2::int8_t, std2::int16_t, std2::int32_t, std2::int64_t;
- std2::uint8_t, std2::uint16_t, std2::uint32_t, std2::uint64_t;
- std2::int_fast8_t, std2::int_fast16_t, std2::int_fast32_t, std2::int_fast64_t;
- std2::uint_fast8_t, std2::uint_fast16_t, std2::uint_fast32_t, std2::uint_fast64_t;
- std2::int_least8_t, std2::int_least16_t, std2::int_least32_t, std2::int_least64_t;
- std2::uint_least8_t, std2::uint_least16_t, std2::uint_least32_t, std2::uint_least64_t;
- std2::uintmax_t
- std2::uintptr_t
- std2::float_t
- std2::double_t
Главным (и, возможно, единственным) отличием от их старых собратьев будет то, что компилятор будет запрещать неявные преобразования значений между этими типами или типами из предыдущих стандартов C++ (включая унаследованные из Си и, ИМХО, совершенно бесполезные в современном мире short, int, long и пр.) Т.е. если мы написали так:
void f(std2::uint32_t n) {...}
То компилятор не позволит нам сделать так:
f(-1);
или так:
f(1.2);
или так:
int i = some_calculation();
f(i);
и даже так:
std2::uint_fast32_t r = another_calculation();
f(f);
То, что новые типы будут определены в новом пространстве имен, позволит не ломать старый код.
Если же в старом коде использовались std::int*_t и мы захотели адаптировать его под новый стандарт, то достаточно будет просто заменить std:: на std2:: простым контекстным поиском.
Мне кажется, что добавление таких типов сделает программирование на C++ более безопасным и предсказуемым с достаточно небольшими затратами.
А вот в то, что в C++ когда-нибудь введут запрет на неявные преобразования между старыми целочисленными типами я не верю. Так и будем жить обмазавшись этим древним говном.