пятница, 21 апреля 2023 г.

[prog.c++.wow] clang++-16 внезапно удивил! Неприятно удивил

Пропробовал собрать SObjectizer clang-ом 16-ой версии. Получил неожиданную ошибку:

clang нашел "ошибку" в коде, которому уже лет семь, если не восемь:

auto e = begin(path) + static_cast< state_t::path_t::difference_type >(
   m_current_state_ptr->nested_level() ) + 1;

где path -- это std::array<const state_t *, max_deep>

Поставить адресную арифметику в C++ под запрет, пусть даже при использовании -Weverything и -Werror, это мощно. Внушаить.

Даже не знаю как к этому относиться.

Конкретно этот кусочек я переписал так:

const auto past_the_end = [&path, this]() {
      auto r = begin(path);
      std::advance( r, m_current_state_ptr->nested_level() + 1u );
      return r;
   }();

Можно было бы и двумя строчками обойтись, как-то вот так:

auto past_the_end = begin(path);
std::advance( past_the_end, m_current_state_ptr->nested_level() + 1u );

но мне не нравится когда нужна, по сути, константа, но ее приходится сперва объявлять в виде обычной переменной, а потом эту переменную отдельно модифицировать. Поэтому был выбран многословный вариант.

Но хуже всего то, что это оказалась только первая ласточка. Затем clang++-16 еще "подозрительные" места нашел. С которыми так же нужно будет что-то сделать.

А самое худшее, что это все вылезло при работе над новой версией SObjectizer. Но ведь и текущую версию 5.7, затем нужно будет под clang++-16 адаптировать...

Не было печали, что называется :(

И, что самое ироничное: новый вариант кода же не стал хоть сколько-нибудь безопаснее.

Так за что боролись, спрашивается?


Upd. Ну а вот от этого я вообще выпадаю в осадок (желающие могут сами проверить на godbolt):

#include <array>

int main() {
#if 1
    char buffer[3];
    buffer[1] = 0;
#else
    std::array<char, 3> buffer;
    buffer[1] = 0;
#endif
}

Вариант с Си-ными массивами, типа, небезопасный. Поэтому ошибка компиляции. А вариант с std::array, надо полагать, безопасный-безопасный. Ага.

Ну ахринеть. Ну уж теперь-то заживем.

понедельник, 17 апреля 2023 г.

[prog.c++] А ведь когда-то в C++ предлагали добавить noexcept(auto) :(

Сегодня довелось написать несколько конструкций noexcept(noexcept(...)). Так себе удовольствие. Захотелось поиметь в языке noexcept(auto). Уже даже собирался набросать пост на эту тему. Но чуть ли не первая строка поиска в Google показала, что подобная идея уже была. Даже в виде двух предложений: N3227 и N4473. По второму предложению известно, что его рассматривали, но не стали принимать, а поставили на паузу (P0133).

В общем, отрадно, что есть люди, которым такая штука кажется полезной. Жаль только, что их недостаточно, чтобы это предложение вошло в стандарт. А для написания шаблонного кода noexcept(auto) оказался бы весьма кстати.