Пропробовал собрать 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, надо полагать, безопасный-безопасный. Ага.
Ну ахринеть. Ну уж теперь-то заживем.